@sima-land/moleculas 15.6.0 → 16.0.0-alpha.1
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/badge/index.js +5 -1
- package/common/components/badge-list/index.d.ts +5 -0
- package/common/components/badge-list/index.js +10 -1
- package/common/components/intractive-image/interactive-image.d.ts +5 -0
- package/common/components/intractive-image/interactive-image.js +24 -1
- package/common/components/product-info/index.d.ts +5 -0
- package/common/components/product-info/index.js +5 -0
- package/common/components/product-info/parts.d.ts +11 -1
- package/common/components/product-info/parts.js +17 -2
- package/common/components/rating-counter/index.d.ts +2 -2
- package/common/types.d.ts +1 -1
- package/desktop/components/breadcrumbs/index.js +5 -1
- package/desktop/components/gallery-modal/components/all-round-view.d.ts +5 -0
- package/desktop/components/gallery-modal/components/all-round-view.js +12 -1
- package/desktop/components/gallery-modal/components/gallery-modal.d.ts +5 -0
- package/desktop/components/gallery-modal/components/gallery-modal.js +15 -1
- package/desktop/components/gallery-modal/components/gallery-modal.module.scss +3 -3
- package/desktop/components/gallery-modal/components/image-overlay.d.ts +6 -1
- package/desktop/components/gallery-modal/components/image-overlay.js +5 -0
- package/desktop/components/gallery-modal/components/review-info.d.ts +5 -0
- package/desktop/components/gallery-modal/components/review-info.js +19 -1
- package/desktop/components/gallery-modal/components/thumbnail.d.ts +5 -0
- package/desktop/components/gallery-modal/components/thumbnail.js +5 -0
- package/desktop/components/gallery-modal/types.d.ts +2 -2
- package/desktop/components/gallery-modal/utils.js +3 -2
- package/desktop/components/modifiers/button/index.js +5 -1
- package/desktop/components/modifiers/group/index.js +10 -1
- package/desktop/components/modifiers/group/modifiers-group.module.scss +2 -0
- package/desktop/components/{person-modal → person-info}/index.d.ts +6 -3
- package/desktop/components/person-info/index.js +46 -0
- package/desktop/components/product-card/index.d.ts +11 -1
- package/desktop/components/product-card/index.js +15 -1
- package/desktop/components/product-carousel/hover-card.js +5 -1
- package/desktop/components/product-carousel/index.d.ts +2 -2
- package/desktop/components/product-carousel/index.js +42 -15
- package/desktop/components/product-carousel/utils.d.ts +2 -3
- package/desktop/components/product-carousel/utils.js +17 -20
- package/desktop/components/promotion-card/banner-title.d.ts +10 -0
- package/desktop/components/promotion-card/banner-title.js +19 -0
- package/desktop/components/promotion-card/estimate.d.ts +5 -0
- package/desktop/components/promotion-card/estimate.js +10 -0
- package/desktop/components/promotion-card/index.js +5 -1
- package/desktop/components/promotion-card/types.d.ts +1 -1
- package/mobile/components/action-circles/action-circles.module.scss +60 -0
- package/mobile/components/action-circles/index.d.ts +22 -0
- package/mobile/components/action-circles/index.js +32 -0
- package/mobile/components/action-list/action-list.module.scss +60 -0
- package/mobile/components/action-list/index.d.ts +23 -0
- package/mobile/components/action-list/index.js +36 -0
- package/mobile/components/breadcrumbs/index.d.ts +5 -0
- package/mobile/components/breadcrumbs/index.js +5 -0
- package/mobile/components/modifiers-list/index.d.ts +9 -9
- package/mobile/components/modifiers-list/index.js +1 -7
- package/mobile/components/modifiers-list/modifier-item/index.d.ts +2 -2
- package/mobile/components/person-info/index.d.ts +44 -0
- package/mobile/components/person-info/index.js +57 -0
- package/mobile/components/product-row/index.d.ts +30 -30
- package/mobile/components/product-row/index.js +40 -51
- package/mobile/components/product-row/product-row.module.scss +0 -1
- package/mobile/components/product-slider/index.d.ts +1 -1
- package/mobile/components/product-slider/index.js +5 -1
- package/mobile/components/search-bar/index.d.ts +1 -1
- package/mobile/components/search-bar/index.js +13 -8
- package/mobile/components/select-screen/index.d.ts +9 -25
- package/mobile/components/select-screen/index.js +14 -35
- package/package.json +47 -43
- package/common/components/adult-block/index.d.ts +0 -16
- package/common/components/adult-block/index.js +0 -40
- package/common/components/quick-view-button/index.d.ts +0 -8
- package/common/components/quick-view-button/index.js +0 -50
- package/common/components/quick-view-button/quick-view-button.module.scss +0 -12
- package/common/components/wish-button/index.d.ts +0 -15
- package/common/components/wish-button/index.js +0 -56
- package/common/components/wish-button/wish-button.module.scss +0 -17
- package/common/helpers/clean-num-string.d.ts +0 -6
- package/common/helpers/clean-num-string.js +0 -13
- package/common/helpers/format-qty-string.d.ts +0 -11
- package/common/helpers/format-qty-string.js +0 -29
- package/common/icons/filled-heart.svg +0 -3
- package/common/icons/heart.svg +0 -3
- package/common/icons/quick-view.svg +0 -3
- package/common/icons/selected.svg +0 -1
- package/common/icons/trash-cart.svg +0 -4
- package/desktop/components/person-modal/index.js +0 -55
- package/mobile/components/garland-calculator-button/garland-calculator-button.module.scss +0 -33
- package/mobile/components/garland-calculator-button/index.d.ts +0 -13
- package/mobile/components/garland-calculator-button/index.js +0 -24
- package/mobile/components/person-screen/index.d.ts +0 -45
- package/mobile/components/person-screen/index.js +0 -80
- package/mobile/components/product-actions-alert/index.d.ts +0 -18
- package/mobile/components/product-actions-alert/index.js +0 -25
- package/mobile/components/product-actions-alert/product-actions-alert.module.scss +0 -36
- /package/desktop/components/{person-modal/person-modal.module.scss → person-info/person-info.module.scss} +0 -0
- /package/mobile/components/{person-screen/person-screen.module.scss → person-info/person-info.module.scss} +0 -0
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ProductInfo, ProductInfoProps } from '../../../common/components/product-info';
|
|
3
3
|
import { PlateProps } from '@sima-land/ui-nucleons/plate';
|
|
4
|
-
export
|
|
4
|
+
export type ProductCardChildren = React.ReactElement<ProductInfoProps, typeof ProductInfo>;
|
|
5
5
|
export interface ProductCardProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
6
6
|
children: ProductCardChildren;
|
|
7
7
|
}
|
|
8
8
|
export declare const HoverCard: React.ForwardRefExoticComponent<PlateProps & React.RefAttributes<HTMLDivElement | null>>;
|
|
9
|
+
/**
|
|
10
|
+
* Карточка данных товара с расширенной инф-ой при наведении.
|
|
11
|
+
* @param props Свойства.
|
|
12
|
+
* @return Элемент.
|
|
13
|
+
*/
|
|
9
14
|
export declare const ProductCard: ({ children, className, ...props }: ProductCardProps) => JSX.Element;
|
|
10
15
|
/**
|
|
11
16
|
* Фильтрует содержимое карточки для вывода состояния без наведения.
|
|
@@ -13,4 +18,9 @@ export declare const ProductCard: ({ children, className, ...props }: ProductCar
|
|
|
13
18
|
* @return Элемент.
|
|
14
19
|
*/
|
|
15
20
|
export declare const reduceBaseInfo: (el: ProductCardChildren) => React.FunctionComponentElement<ProductInfoProps>;
|
|
21
|
+
/**
|
|
22
|
+
* Получив содержимое карточки фильтрует/меняет его для вывода в карточке при наведении.
|
|
23
|
+
* @param el Содержимое.
|
|
24
|
+
* @return Элемент.
|
|
25
|
+
*/
|
|
16
26
|
export declare const reduceHoverInfo: (el: ProductCardChildren) => React.FunctionComponentElement<ProductInfoProps>;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
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);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -44,6 +48,11 @@ exports.HoverCard = (0, react_1.forwardRef)((props, ref) => {
|
|
|
44
48
|
const layer = (0, layer_1.useLayer)() + 1;
|
|
45
49
|
return (react_1.default.createElement(plate_1.Plate, Object.assign({}, props, { style: Object.assign(Object.assign({}, props.style), { zIndex: layer }), ref: ref, rounds: 'm', shadow: 'z4', className: (0, classnames_1.default)(product_card_module_scss_1.default.card, props.className), "data-testid": 'product-card:hover-card' })));
|
|
46
50
|
});
|
|
51
|
+
/**
|
|
52
|
+
* Карточка данных товара с расширенной инф-ой при наведении.
|
|
53
|
+
* @param props Свойства.
|
|
54
|
+
* @return Элемент.
|
|
55
|
+
*/
|
|
47
56
|
const ProductCard = (_a) => {
|
|
48
57
|
var { children, className } = _a, props = __rest(_a, ["children", "className"]);
|
|
49
58
|
const [hovered, toggle] = (0, react_1.useState)(false);
|
|
@@ -82,6 +91,11 @@ const reduceBaseInfo = (el) => (0, react_1.cloneElement)(el, {
|
|
|
82
91
|
}),
|
|
83
92
|
});
|
|
84
93
|
exports.reduceBaseInfo = reduceBaseInfo;
|
|
94
|
+
/**
|
|
95
|
+
* Получив содержимое карточки фильтрует/меняет его для вывода в карточке при наведении.
|
|
96
|
+
* @param el Содержимое.
|
|
97
|
+
* @return Элемент.
|
|
98
|
+
*/
|
|
85
99
|
const reduceHoverInfo = (el) => (0, react_1.cloneElement)(el, {
|
|
86
100
|
// при наведении у изображения строго непрозрачность = 1
|
|
87
101
|
children: react_1.Children.map(el.props.children, child => (0, react_1.isValidElement)(child) && child.type === product_info_1.Parts.Image
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
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);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -7,7 +7,7 @@ interface ItemSize {
|
|
|
7
7
|
l?: 2 | 3 | 4;
|
|
8
8
|
xl?: 2 | 3 | 4;
|
|
9
9
|
}
|
|
10
|
-
export
|
|
10
|
+
export type ItemElement = React.ReactElement<ProductInfoProps, typeof ProductInfo>;
|
|
11
11
|
export interface ProductCarouselProps {
|
|
12
12
|
/** CSS-класс для корневого элемента. */
|
|
13
13
|
className?: string;
|
|
@@ -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 {};
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
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);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -34,6 +38,7 @@ const bind_1 = __importDefault(require("classnames/bind"));
|
|
|
34
38
|
const product_carousel_module_scss_1 = __importDefault(require("./product-carousel.module.scss"));
|
|
35
39
|
const layer_1 = require("@sima-land/ui-nucleons/helpers/layer");
|
|
36
40
|
const cx = bind_1.default.bind(product_carousel_module_scss_1.default);
|
|
41
|
+
// eslint-disable-next-line require-jsdoc
|
|
37
42
|
const getSizeClasses = (size = {}) => [
|
|
38
43
|
`size-xs-${size.xs || 4}`,
|
|
39
44
|
`size-s-${size.s || 3}`,
|
|
@@ -46,7 +51,7 @@ const getSizeClasses = (size = {}) => [
|
|
|
46
51
|
* @param props Свойства.
|
|
47
52
|
* @return Элемент.
|
|
48
53
|
*/
|
|
49
|
-
|
|
54
|
+
function ProductCarousel({ className, itemSize, onInViewport, onNeedRequest, withHoverCard, children, }) {
|
|
50
55
|
const layer = (0, layer_1.useLayer)();
|
|
51
56
|
const [activeItemIndex, setActiveItemIndex] = (0, react_1.useState)(null);
|
|
52
57
|
const cardShow = (0, utils_1.useAllowFlag)();
|
|
@@ -61,7 +66,8 @@ const ProductCarousel = ({ className, itemSize, onInViewport, onNeedRequest, wit
|
|
|
61
66
|
items = children ? [children] : [];
|
|
62
67
|
}
|
|
63
68
|
// вычисляем ширину элемента карусели для позиционирования стрелок
|
|
64
|
-
const
|
|
69
|
+
const firstItemRef = (0, react_1.useRef)(null);
|
|
70
|
+
const itemWidth = (0, utils_1.useClientWidth)(firstItemRef, [items.length]);
|
|
65
71
|
// инициируем загрузку данных, когда компонент почти попал в зону видимости
|
|
66
72
|
const options = (0, react_1.useMemo)(() => ({ rootMargin: '200px 0px 200px 0px' }), []);
|
|
67
73
|
(0, intersection_1.useIntersection)(rootRef, entry => {
|
|
@@ -83,21 +89,12 @@ const ProductCarousel = ({ className, itemSize, onInViewport, onNeedRequest, wit
|
|
|
83
89
|
top: `${itemWidth / 2}px`,
|
|
84
90
|
},
|
|
85
91
|
},
|
|
86
|
-
}), { 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 => {
|
|
87
93
|
if (cardShow.allowed()) {
|
|
88
94
|
targetItemRef.current = e.currentTarget;
|
|
89
95
|
setActiveItemIndex(index);
|
|
90
96
|
}
|
|
91
|
-
} },
|
|
92
|
-
children: react_1.Children.toArray(item.props.children).reduce((list, child) => {
|
|
93
|
-
if ((0, react_1.isValidElement)(child)) {
|
|
94
|
-
child.type === product_info_1.Parts.Image &&
|
|
95
|
-
list.push(withHoverCard ? (0, react_1.cloneElement)(child, { children: undefined }) : child);
|
|
96
|
-
child.type !== product_info_1.Parts.Footer && list.push(child);
|
|
97
|
-
}
|
|
98
|
-
return list;
|
|
99
|
-
}, []),
|
|
100
|
-
}))),
|
|
97
|
+
} }, item)),
|
|
101
98
|
// длительность прокрутки в Carousel - 320, делаем слегка с запасом
|
|
102
99
|
// @todo после восстановления проверить позицию курсора чтобы показать карточку (если будет критично)
|
|
103
100
|
onChangeTargetIndex: () => cardShow.disallowFor(360) }))),
|
|
@@ -105,5 +102,35 @@ const ProductCarousel = ({ className, itemSize, onInViewport, onNeedRequest, wit
|
|
|
105
102
|
activeItemIndex !== null &&
|
|
106
103
|
items[activeItemIndex] &&
|
|
107
104
|
[items[activeItemIndex]].map(item => (react_1.default.createElement(hover_card_1.HoverCard, Object.assign({ key: activeItemIndex, targetRef: targetItemRef, onMouseLeave: () => setActiveItemIndex(null) }, item.props))))));
|
|
108
|
-
}
|
|
105
|
+
}
|
|
109
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;
|
|
@@ -5,7 +5,17 @@ export interface BannerTitleProps {
|
|
|
5
5
|
volumeDiscount?: number;
|
|
6
6
|
dueDate?: Date;
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* Заголовок баннера.
|
|
10
|
+
* @param props Свойства.
|
|
11
|
+
* @return Элемент.
|
|
12
|
+
*/
|
|
8
13
|
export declare const BannerTitle: ({ promotionType, volumeDiscount, dueDate }: BannerTitleProps) => JSX.Element;
|
|
14
|
+
/**
|
|
15
|
+
* Таймер.
|
|
16
|
+
* @param props Свойства.
|
|
17
|
+
* @return Элемент.
|
|
18
|
+
*/
|
|
9
19
|
export declare const CustomTimer: ({ dueDate }: {
|
|
10
20
|
dueDate: Date;
|
|
11
21
|
}) => JSX.Element;
|
|
@@ -8,6 +8,11 @@ const react_1 = __importDefault(require("react"));
|
|
|
8
8
|
const timer_1 = require("@sima-land/ui-nucleons/timer");
|
|
9
9
|
const date_fns_1 = require("date-fns");
|
|
10
10
|
const banner_title_module_scss_1 = __importDefault(require("./banner-title.module.scss"));
|
|
11
|
+
/**
|
|
12
|
+
* Заголовок баннера.
|
|
13
|
+
* @param props Свойства.
|
|
14
|
+
* @return Элемент.
|
|
15
|
+
*/
|
|
11
16
|
const BannerTitle = ({ promotionType, volumeDiscount, dueDate }) => {
|
|
12
17
|
let content = null;
|
|
13
18
|
switch (promotionType) {
|
|
@@ -32,6 +37,11 @@ const BannerTitle = ({ promotionType, volumeDiscount, dueDate }) => {
|
|
|
32
37
|
return react_1.default.createElement(react_1.default.Fragment, null, content);
|
|
33
38
|
};
|
|
34
39
|
exports.BannerTitle = BannerTitle;
|
|
40
|
+
/**
|
|
41
|
+
* Таймер.
|
|
42
|
+
* @param props Свойства.
|
|
43
|
+
* @return Элемент.
|
|
44
|
+
*/
|
|
35
45
|
const CustomTimer = ({ dueDate }) => (react_1.default.createElement(timer_1.Timer, { date: (0, date_fns_1.formatISO)(dueDate), timeout: 1000 * 60, format: ({ days, hours, minutes }) => (react_1.default.createElement("div", { className: banner_title_module_scss_1.default.timer, "data-testid": 'promotion-card:banner-timer' },
|
|
36
46
|
react_1.default.createElement(TimerPart, { label: '\u0434\u043D\u0435\u0439', value: Math.min(99, days) }),
|
|
37
47
|
react_1.default.createElement(TimerDivider, null),
|
|
@@ -39,7 +49,16 @@ const CustomTimer = ({ dueDate }) => (react_1.default.createElement(timer_1.Time
|
|
|
39
49
|
react_1.default.createElement(TimerDivider, null),
|
|
40
50
|
react_1.default.createElement(TimerPart, { label: '\u043C\u0438\u043D\u0443\u0442', value: minutes % 60 }))) }));
|
|
41
51
|
exports.CustomTimer = CustomTimer;
|
|
52
|
+
/**
|
|
53
|
+
* Часть таймера.
|
|
54
|
+
* @param props Свойства.
|
|
55
|
+
* @return Элемент.
|
|
56
|
+
*/
|
|
42
57
|
const TimerPart = ({ label, value }) => (react_1.default.createElement("div", { className: banner_title_module_scss_1.default.part },
|
|
43
58
|
react_1.default.createElement("div", null, `${value}`.padStart(2, '0')),
|
|
44
59
|
react_1.default.createElement("div", { className: banner_title_module_scss_1.default.label }, label)));
|
|
60
|
+
/**
|
|
61
|
+
* Разделитель частей таймера.
|
|
62
|
+
* @return Элемент.
|
|
63
|
+
*/
|
|
45
64
|
const TimerDivider = () => react_1.default.createElement("div", { className: banner_title_module_scss_1.default.divider }, ":");
|
|
@@ -20,7 +20,17 @@ const MONTH_SHORT_NAME = [
|
|
|
20
20
|
'ноя',
|
|
21
21
|
'дек',
|
|
22
22
|
];
|
|
23
|
+
/**
|
|
24
|
+
* Получив число возвращает его строковое отображение.
|
|
25
|
+
* @param n Число.
|
|
26
|
+
* @return Отображение.
|
|
27
|
+
*/
|
|
23
28
|
const toTimePart = (n) => `${n}`.padStart(2, '0');
|
|
29
|
+
/**
|
|
30
|
+
* Оставшееся время.
|
|
31
|
+
* @param props Свойства.
|
|
32
|
+
* @return Элемент.
|
|
33
|
+
*/
|
|
24
34
|
const Estimate = ({ dueDate }) => {
|
|
25
35
|
const now = new Date();
|
|
26
36
|
let content = null;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
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);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export type PromotionType = 'gift' | '3-by-2' | 'special' | 'volume-discount';
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
@use 'node_modules/@sima-land/ui-nucleons/colors';
|
|
2
|
+
@use 'node_modules/@sima-land/ui-nucleons/utils';
|
|
3
|
+
|
|
4
|
+
.circles {
|
|
5
|
+
display: flex;
|
|
6
|
+
justify-content: center;
|
|
7
|
+
padding: 48px 32px;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.circles-item {
|
|
11
|
+
display: inline-flex;
|
|
12
|
+
align-items: center;
|
|
13
|
+
flex-direction: column;
|
|
14
|
+
text-align: center;
|
|
15
|
+
box-sizing: content-box;
|
|
16
|
+
width: 88px;
|
|
17
|
+
margin: 0 12px;
|
|
18
|
+
cursor: pointer;
|
|
19
|
+
.icon-wrapper {
|
|
20
|
+
display: flex;
|
|
21
|
+
align-items: center;
|
|
22
|
+
justify-content: center;
|
|
23
|
+
background: colors.$basic-gray4;
|
|
24
|
+
width: 56px;
|
|
25
|
+
height: 56px;
|
|
26
|
+
border-radius: 50%;
|
|
27
|
+
margin-bottom: 12px;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.list {
|
|
32
|
+
padding: 12px 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.list-item {
|
|
36
|
+
@include utils.reset-button;
|
|
37
|
+
width: 100%;
|
|
38
|
+
display: flex;
|
|
39
|
+
align-items: center;
|
|
40
|
+
justify-content: center;
|
|
41
|
+
text-align: center;
|
|
42
|
+
height: 48px;
|
|
43
|
+
font-weight: 400;
|
|
44
|
+
font-size: 16px;
|
|
45
|
+
line-height: 24px;
|
|
46
|
+
text-decoration: none;
|
|
47
|
+
cursor: pointer;
|
|
48
|
+
&.basic-gray87 {
|
|
49
|
+
color: colors.$basic-gray87;
|
|
50
|
+
&:hover {
|
|
51
|
+
color: colors.$basic-gray54;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
&.additional-red {
|
|
55
|
+
color: colors.$additional-red;
|
|
56
|
+
&:hover {
|
|
57
|
+
color: colors.$additional-deep-red;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { LinkProps } from '@sima-land/ui-nucleons/link';
|
|
3
|
+
export interface ActionCirclesProps {
|
|
4
|
+
/** Кнопки. */
|
|
5
|
+
children?: ReactNode;
|
|
6
|
+
}
|
|
7
|
+
export interface ActionCircleItemProps extends Pick<LinkProps, 'href' | 'pseudo' | 'onClick'> {
|
|
8
|
+
/** Название. */
|
|
9
|
+
title: string;
|
|
10
|
+
/** Иконка. */
|
|
11
|
+
icon: ReactNode;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Кнопки действий с иконками.
|
|
15
|
+
* Используется вместе с `Alert`.
|
|
16
|
+
* @param props Свойства.
|
|
17
|
+
* @return Элемент.
|
|
18
|
+
*/
|
|
19
|
+
export declare function ActionCircles({ children }: ActionCirclesProps): JSX.Element;
|
|
20
|
+
export declare namespace ActionCircles {
|
|
21
|
+
var Item: ({ icon, title, href, onClick, }: ActionCircleItemProps) => JSX.Element;
|
|
22
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ActionCircles = void 0;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
const link_1 = require("@sima-land/ui-nucleons/link");
|
|
9
|
+
const bind_1 = __importDefault(require("classnames/bind"));
|
|
10
|
+
const action_circles_module_scss_1 = __importDefault(require("./action-circles.module.scss"));
|
|
11
|
+
const cx = bind_1.default.bind(action_circles_module_scss_1.default);
|
|
12
|
+
/**
|
|
13
|
+
* Кнопки действий с иконками.
|
|
14
|
+
* Используется вместе с `Alert`.
|
|
15
|
+
* @param props Свойства.
|
|
16
|
+
* @return Элемент.
|
|
17
|
+
*/
|
|
18
|
+
function ActionCircles({ children }) {
|
|
19
|
+
return react_1.default.createElement("div", { className: cx('circles') }, children);
|
|
20
|
+
}
|
|
21
|
+
exports.ActionCircles = ActionCircles;
|
|
22
|
+
/**
|
|
23
|
+
* Кнопка действия с иконкой.
|
|
24
|
+
* @param props Свойства.
|
|
25
|
+
* @return Элемент.
|
|
26
|
+
*/
|
|
27
|
+
ActionCircles.Item = function ActionCircleItem({ icon, title, href, onClick, }) {
|
|
28
|
+
// @todo перейти на TextButton из нуклонов
|
|
29
|
+
return (react_1.default.createElement(link_1.Link, { href: href, className: cx('circles-item'), color: 'basic-gray87', onClick: onClick, "data-testid": 'action-circles:item' },
|
|
30
|
+
react_1.default.createElement("span", { className: cx('icon-wrapper') }, icon),
|
|
31
|
+
title));
|
|
32
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
@use 'node_modules/@sima-land/ui-nucleons/colors';
|
|
2
|
+
@use 'node_modules/@sima-land/ui-nucleons/utils';
|
|
3
|
+
|
|
4
|
+
.circles {
|
|
5
|
+
display: flex;
|
|
6
|
+
justify-content: center;
|
|
7
|
+
padding: 48px 32px;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.circles-item {
|
|
11
|
+
display: inline-flex;
|
|
12
|
+
align-items: center;
|
|
13
|
+
flex-direction: column;
|
|
14
|
+
text-align: center;
|
|
15
|
+
box-sizing: content-box;
|
|
16
|
+
width: 88px;
|
|
17
|
+
margin: 0 12px;
|
|
18
|
+
cursor: pointer;
|
|
19
|
+
.icon-wrapper {
|
|
20
|
+
display: flex;
|
|
21
|
+
align-items: center;
|
|
22
|
+
justify-content: center;
|
|
23
|
+
background: colors.$basic-gray4;
|
|
24
|
+
width: 56px;
|
|
25
|
+
height: 56px;
|
|
26
|
+
border-radius: 50%;
|
|
27
|
+
margin-bottom: 12px;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.list {
|
|
32
|
+
padding: 12px 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.list-item {
|
|
36
|
+
@include utils.reset-button;
|
|
37
|
+
width: 100%;
|
|
38
|
+
display: flex;
|
|
39
|
+
align-items: center;
|
|
40
|
+
justify-content: center;
|
|
41
|
+
text-align: center;
|
|
42
|
+
height: 48px;
|
|
43
|
+
font-weight: 400;
|
|
44
|
+
font-size: 16px;
|
|
45
|
+
line-height: 24px;
|
|
46
|
+
text-decoration: none;
|
|
47
|
+
cursor: pointer;
|
|
48
|
+
&.basic-gray87 {
|
|
49
|
+
color: colors.$basic-gray87;
|
|
50
|
+
&:hover {
|
|
51
|
+
color: colors.$basic-gray54;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
&.additional-red {
|
|
55
|
+
color: colors.$additional-red;
|
|
56
|
+
&:hover {
|
|
57
|
+
color: colors.$additional-deep-red;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { MouseEventHandler, ReactNode } from 'react';
|
|
2
|
+
import { Token } from '@sima-land/ui-nucleons/colors';
|
|
3
|
+
export interface ActionsListProps {
|
|
4
|
+
/** Кнопки. */
|
|
5
|
+
children?: ReactNode;
|
|
6
|
+
}
|
|
7
|
+
export interface ActionsListItemProps {
|
|
8
|
+
children?: ReactNode;
|
|
9
|
+
as?: 'anchor' | 'button';
|
|
10
|
+
href?: string;
|
|
11
|
+
onClick?: MouseEventHandler;
|
|
12
|
+
color?: Extract<Token, 'basic-gray87' | 'additional-red'>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Список действий.
|
|
16
|
+
* Используется вместе с `Alert`.
|
|
17
|
+
* @param props Свойства.
|
|
18
|
+
* @return Элемент.
|
|
19
|
+
*/
|
|
20
|
+
export declare function ActionList({ children }: ActionsListProps): JSX.Element;
|
|
21
|
+
export declare namespace ActionList {
|
|
22
|
+
var Item: ({ children, as, href, onClick, color, }: ActionsListItemProps) => JSX.Element;
|
|
23
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ActionList = void 0;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
const bind_1 = __importDefault(require("classnames/bind"));
|
|
9
|
+
const action_list_module_scss_1 = __importDefault(require("./action-list.module.scss"));
|
|
10
|
+
const cx = bind_1.default.bind(action_list_module_scss_1.default);
|
|
11
|
+
/**
|
|
12
|
+
* Список действий.
|
|
13
|
+
* Используется вместе с `Alert`.
|
|
14
|
+
* @param props Свойства.
|
|
15
|
+
* @return Элемент.
|
|
16
|
+
*/
|
|
17
|
+
function ActionList({ children }) {
|
|
18
|
+
return react_1.default.createElement("div", { className: cx('list') }, children);
|
|
19
|
+
}
|
|
20
|
+
exports.ActionList = ActionList;
|
|
21
|
+
/**
|
|
22
|
+
* Элемент списка действий.
|
|
23
|
+
* @param props Свойства.
|
|
24
|
+
* @return Элемент.
|
|
25
|
+
*/
|
|
26
|
+
ActionList.Item = function ActionListItem({ children, as = 'button', href, onClick, color = 'basic-gray87', }) {
|
|
27
|
+
const className = cx('list-item', { [color]: color });
|
|
28
|
+
const testId = 'action-list:item';
|
|
29
|
+
// @todo перейти на TextButton из нуклонов
|
|
30
|
+
if (as === 'anchor') {
|
|
31
|
+
return (react_1.default.createElement("a", { className: className, "data-testid": testId, href: href, onClick: onClick }, children));
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
return (react_1.default.createElement("button", { type: 'button', className: className, "data-testid": testId, onClick: onClick }, children));
|
|
35
|
+
}
|
|
36
|
+
};
|
|
@@ -7,5 +7,10 @@ exports.Breadcrumbs = void 0;
|
|
|
7
7
|
const link_1 = require("@sima-land/ui-nucleons/link");
|
|
8
8
|
const react_1 = __importDefault(require("react"));
|
|
9
9
|
const breadcrumbs_module_scss_1 = __importDefault(require("./breadcrumbs.module.scss"));
|
|
10
|
+
/**
|
|
11
|
+
* Хлебные крошки.
|
|
12
|
+
* @param props Свойства.
|
|
13
|
+
* @return Элемент.
|
|
14
|
+
*/
|
|
10
15
|
const Breadcrumbs = ({ items }) => (react_1.default.createElement("nav", { className: breadcrumbs_module_scss_1.default.root }, items.map((item, index) => (react_1.default.createElement(link_1.Link, { key: index, href: item.url, pseudo: !item.url, color: 'basic-gray87', className: breadcrumbs_module_scss_1.default.item, "data-testid": 'breadcrumb' }, item.name)))));
|
|
11
16
|
exports.Breadcrumbs = Breadcrumbs;
|