@gravity-ui/page-constructor 1.6.1 → 1.7.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/build/cjs/blocks/ExtendedFeatures/ExtendedFeatures.css +6 -1
- package/build/cjs/blocks/ExtendedFeatures/ExtendedFeatures.js +26 -12
- package/build/cjs/components/RouterLink/RouterLink.d.ts +1 -0
- package/build/cjs/components/navigation/components/Header/Header.css +85 -0
- package/build/cjs/components/navigation/components/Header/Header.d.ts +28 -0
- package/build/cjs/components/navigation/components/Header/Header.js +81 -0
- package/build/cjs/components/navigation/components/Logo/Logo.css +18 -0
- package/build/cjs/components/navigation/components/Logo/Logo.d.ts +7 -0
- package/build/cjs/components/navigation/components/Logo/Logo.js +13 -0
- package/build/cjs/components/navigation/components/MobileNavigation/MobileNavigation.css +58 -0
- package/build/cjs/components/navigation/components/MobileNavigation/MobileNavigation.d.ts +13 -0
- package/build/cjs/components/navigation/components/MobileNavigation/MobileNavigation.js +45 -0
- package/build/cjs/components/navigation/components/Navigation/Navigation.css +43 -0
- package/build/cjs/components/navigation/components/Navigation/Navigation.d.ts +11 -0
- package/build/cjs/components/navigation/components/Navigation/Navigation.js +70 -0
- package/build/cjs/components/navigation/components/NavigationItem/NavigationItem.css +40 -0
- package/build/cjs/components/navigation/components/NavigationItem/NavigationItem.d.ts +12 -0
- package/build/cjs/components/navigation/components/NavigationItem/NavigationItem.js +47 -0
- package/build/cjs/components/navigation/components/NavigationPopup/NavigationPopup.css +33 -0
- package/build/cjs/components/navigation/components/NavigationPopup/NavigationPopup.d.ts +24 -0
- package/build/cjs/components/navigation/components/NavigationPopup/NavigationPopup.js +57 -0
- package/build/cjs/components/navigation/components/SocialIcon/SocialIcon.css +20 -0
- package/build/cjs/components/navigation/components/SocialIcon/SocialIcon.d.ts +7 -0
- package/build/cjs/components/navigation/components/SocialIcon/SocialIcon.js +10 -0
- package/build/cjs/containers/PageConstructor/PageConstructor.d.ts +2 -0
- package/build/cjs/containers/PageConstructor/PageConstructor.js +4 -2
- package/build/cjs/context/locationContext/locationContext.d.ts +1 -0
- package/build/cjs/icons/NavigationArrow.d.ts +2 -0
- package/build/cjs/icons/NavigationArrow.js +9 -0
- package/build/cjs/icons/NavigationClose.d.ts +2 -0
- package/build/cjs/icons/NavigationClose.js +9 -0
- package/build/cjs/icons/NavigationOpen.d.ts +2 -0
- package/build/cjs/icons/NavigationOpen.js +11 -0
- package/build/cjs/icons/index.d.ts +3 -0
- package/build/cjs/icons/index.js +3 -0
- package/build/cjs/models/constructor-items/blocks.d.ts +3 -1
- package/build/cjs/models/navigation.d.ts +59 -0
- package/build/cjs/models/navigation.js +10 -0
- package/build/cjs/text-transform/blocks.js +6 -1
- package/build/esm/blocks/ExtendedFeatures/ExtendedFeatures.css +6 -1
- package/build/esm/blocks/ExtendedFeatures/ExtendedFeatures.js +28 -14
- package/build/esm/components/RouterLink/RouterLink.d.ts +1 -0
- package/build/esm/components/navigation/components/Header/Header.css +85 -0
- package/build/esm/components/navigation/components/Header/Header.d.ts +29 -0
- package/build/esm/components/navigation/components/Header/Header.js +79 -0
- package/build/esm/components/navigation/components/Logo/Logo.css +18 -0
- package/build/esm/components/navigation/components/Logo/Logo.d.ts +8 -0
- package/build/esm/components/navigation/components/Logo/Logo.js +11 -0
- package/build/esm/components/navigation/components/MobileNavigation/MobileNavigation.css +58 -0
- package/build/esm/components/navigation/components/MobileNavigation/MobileNavigation.d.ts +14 -0
- package/build/esm/components/navigation/components/MobileNavigation/MobileNavigation.js +43 -0
- package/build/esm/components/navigation/components/Navigation/Navigation.css +43 -0
- package/build/esm/components/navigation/components/Navigation/Navigation.d.ts +12 -0
- package/build/esm/components/navigation/components/Navigation/Navigation.js +69 -0
- package/build/esm/components/navigation/components/NavigationItem/NavigationItem.css +40 -0
- package/build/esm/components/navigation/components/NavigationItem/NavigationItem.d.ts +13 -0
- package/build/esm/components/navigation/components/NavigationItem/NavigationItem.js +46 -0
- package/build/esm/components/navigation/components/NavigationPopup/NavigationPopup.css +33 -0
- package/build/esm/components/navigation/components/NavigationPopup/NavigationPopup.d.ts +25 -0
- package/build/esm/components/navigation/components/NavigationPopup/NavigationPopup.js +54 -0
- package/build/esm/components/navigation/components/SocialIcon/SocialIcon.css +20 -0
- package/build/esm/components/navigation/components/SocialIcon/SocialIcon.d.ts +8 -0
- package/build/esm/components/navigation/components/SocialIcon/SocialIcon.js +8 -0
- package/build/esm/containers/PageConstructor/PageConstructor.d.ts +2 -0
- package/build/esm/containers/PageConstructor/PageConstructor.js +4 -2
- package/build/esm/context/locationContext/locationContext.d.ts +1 -0
- package/build/esm/icons/NavigationArrow.d.ts +2 -0
- package/build/esm/icons/NavigationArrow.js +4 -0
- package/build/esm/icons/NavigationClose.d.ts +2 -0
- package/build/esm/icons/NavigationClose.js +4 -0
- package/build/esm/icons/NavigationOpen.d.ts +2 -0
- package/build/esm/icons/NavigationOpen.js +6 -0
- package/build/esm/icons/index.d.ts +3 -0
- package/build/esm/icons/index.js +3 -0
- package/build/esm/models/constructor-items/blocks.d.ts +3 -1
- package/build/esm/models/navigation.d.ts +59 -0
- package/build/esm/models/navigation.js +7 -0
- package/build/esm/text-transform/blocks.js +6 -1
- package/package.json +4 -1
- package/server/models/constructor-items/blocks.d.ts +3 -1
- package/server/text-transform/blocks.js +6 -1
- package/styles/mixins.scss +38 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.7.0](https://github.com/gravity-ui/page-constructor/compare/v1.6.1...v1.7.0) (2022-11-10)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **ExtendedFeatures:** add content ([#51](https://github.com/gravity-ui/page-constructor/issues/51)) ([0990563](https://github.com/gravity-ui/page-constructor/commit/0990563a62c3f8f4d4cfb206cedb7a1205cb1797))
|
|
9
|
+
|
|
3
10
|
## [1.6.1](https://github.com/gravity-ui/page-constructor/compare/v1.4.1...v1.6.1) (2022-11-10)
|
|
4
11
|
|
|
5
12
|
### Bug Fixes
|
|
@@ -12,6 +12,8 @@ unpredictable css rules order in build */
|
|
|
12
12
|
}
|
|
13
13
|
.pc-ExtendedFeaturesBlock__item {
|
|
14
14
|
margin-top: 32px;
|
|
15
|
+
}
|
|
16
|
+
.pc-ExtendedFeaturesBlock__item.col {
|
|
15
17
|
padding-right: 32px;
|
|
16
18
|
}
|
|
17
19
|
.pc-ExtendedFeaturesBlock__item-title {
|
|
@@ -74,12 +76,15 @@ unpredictable css rules order in build */
|
|
|
74
76
|
height: 32px;
|
|
75
77
|
background-size: cover;
|
|
76
78
|
display: block;
|
|
77
|
-
margin-bottom:
|
|
79
|
+
margin-bottom: 12px;
|
|
78
80
|
}
|
|
79
81
|
@media (max-width: 577px) {
|
|
80
82
|
.pc-ExtendedFeaturesBlock__item {
|
|
81
83
|
margin-top: 32px;
|
|
82
84
|
}
|
|
85
|
+
.pc-ExtendedFeaturesBlock__item.col {
|
|
86
|
+
padding-right: 8px;
|
|
87
|
+
}
|
|
83
88
|
}
|
|
84
89
|
@media (min-width: 769px) {
|
|
85
90
|
.pc-ExtendedFeaturesBlock.pc-AnimateBlock .pc-ExtendedFeaturesBlock__item, .pc-AnimateBlock .pc-ExtendedFeaturesBlock .pc-ExtendedFeaturesBlock__item {
|
|
@@ -2,26 +2,40 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ExtendedFeaturesBlock = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
-
const react_1 = (0, tslib_1.
|
|
5
|
+
const react_1 = (0, tslib_1.__importStar)(require("react"));
|
|
6
6
|
const utils_1 = require("../../utils");
|
|
7
7
|
const grid_1 = require("../../grid");
|
|
8
8
|
const components_1 = require("../../components/");
|
|
9
|
+
const sub_blocks_1 = require("../../sub-blocks");
|
|
10
|
+
const Image_1 = (0, tslib_1.__importDefault)(require("../../components/Image/Image"));
|
|
11
|
+
const ThemeValueContext_1 = require("../../context/theme/ThemeValueContext");
|
|
12
|
+
const utils_2 = require("../../components/Media/Image/utils");
|
|
9
13
|
const b = (0, utils_1.block)('ExtendedFeaturesBlock');
|
|
10
14
|
const DEFAULT_SIZES = {
|
|
11
15
|
all: 12,
|
|
12
16
|
sm: 6,
|
|
13
17
|
md: 4,
|
|
14
18
|
};
|
|
15
|
-
const ExtendedFeaturesBlock = ({ title, description, items, colSizes = DEFAULT_SIZES, animated, }) =>
|
|
16
|
-
|
|
17
|
-
react_1.default.createElement(
|
|
18
|
-
react_1.default.createElement(
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
const ExtendedFeaturesBlock = ({ title, description, items, colSizes = DEFAULT_SIZES, animated, }) => {
|
|
20
|
+
const { themeValue: theme } = (0, react_1.useContext)(ThemeValueContext_1.ThemeValueContext);
|
|
21
|
+
return (react_1.default.createElement(components_1.AnimateBlock, { className: b(), animate: animated },
|
|
22
|
+
react_1.default.createElement(components_1.BlockHeader, { title: title, description: description, className: b('header') }),
|
|
23
|
+
react_1.default.createElement("div", { className: b('items') },
|
|
24
|
+
react_1.default.createElement(grid_1.Row, null, items.map(({ title: itemTitle, text, link, links, label, icon }) => {
|
|
25
|
+
const itemLinks = links || [];
|
|
26
|
+
const iconThemed = icon && (0, utils_1.getThemedValue)(icon, theme);
|
|
27
|
+
const iconData = iconThemed && (0, utils_2.getMediaImage)(iconThemed);
|
|
28
|
+
if (link) {
|
|
29
|
+
itemLinks.push(link);
|
|
30
|
+
}
|
|
31
|
+
return (react_1.default.createElement(grid_1.Col, { className: b('item'), key: text || itemTitle, sizes: colSizes },
|
|
32
|
+
iconData && react_1.default.createElement(Image_1.default, Object.assign({}, iconData, { className: b('icon') })),
|
|
33
|
+
react_1.default.createElement("div", { className: b('container') },
|
|
34
|
+
itemTitle && (react_1.default.createElement("h5", { className: b('item-title') },
|
|
35
|
+
react_1.default.createElement(components_1.HTML, null, itemTitle),
|
|
36
|
+
label && (react_1.default.createElement("div", { className: b('item-label') }, label)))),
|
|
37
|
+
react_1.default.createElement(sub_blocks_1.Content, { text: text, links: itemLinks, size: "s", colSizes: { all: 12, md: 12 } }))));
|
|
38
|
+
})))));
|
|
39
|
+
};
|
|
26
40
|
exports.ExtendedFeaturesBlock = ExtendedFeaturesBlock;
|
|
27
41
|
exports.default = exports.ExtendedFeaturesBlock;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/* use this for style redefinitions to awoid problems with
|
|
2
|
+
unpredictable css rules order in build */
|
|
3
|
+
.header {
|
|
4
|
+
position: sticky;
|
|
5
|
+
z-index: 98;
|
|
6
|
+
top: 0;
|
|
7
|
+
display: flex;
|
|
8
|
+
justify-content: center;
|
|
9
|
+
align-items: center;
|
|
10
|
+
height: var(--header-height);
|
|
11
|
+
background-color: var(--yc-color-base-background);
|
|
12
|
+
box-shadow: inset 0px -1px 0px var(--yc-color-line-generic);
|
|
13
|
+
}
|
|
14
|
+
.header__wrapper {
|
|
15
|
+
display: flex;
|
|
16
|
+
justify-content: space-between;
|
|
17
|
+
align-items: center;
|
|
18
|
+
height: var(--header-height);
|
|
19
|
+
}
|
|
20
|
+
@media (min-width: 769px) {
|
|
21
|
+
.header__mobile-menu-button {
|
|
22
|
+
display: none;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
.header__navigation, .header__left, .header__right {
|
|
26
|
+
display: flex;
|
|
27
|
+
align-items: center;
|
|
28
|
+
}
|
|
29
|
+
.header__navigation {
|
|
30
|
+
position: relative;
|
|
31
|
+
flex: 1 0 0;
|
|
32
|
+
justify-content: flex-start;
|
|
33
|
+
margin-right: 20px;
|
|
34
|
+
}
|
|
35
|
+
@media (max-width: 768px) {
|
|
36
|
+
.header__navigation {
|
|
37
|
+
display: none;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
.header__right {
|
|
41
|
+
flex: 0;
|
|
42
|
+
justify-content: flex-end;
|
|
43
|
+
}
|
|
44
|
+
.header__navigation-container {
|
|
45
|
+
display: flex;
|
|
46
|
+
overflow-x: hidden;
|
|
47
|
+
flex: 1 0 0;
|
|
48
|
+
justify-content: space-between;
|
|
49
|
+
align-items: center;
|
|
50
|
+
margin-right: 20px;
|
|
51
|
+
}
|
|
52
|
+
.header__buttons {
|
|
53
|
+
display: flex;
|
|
54
|
+
}
|
|
55
|
+
@media (max-width: 768px) {
|
|
56
|
+
.header__buttons {
|
|
57
|
+
display: none;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
.header__buttons > *:not(:last-child) {
|
|
61
|
+
margin-right: 16px;
|
|
62
|
+
}
|
|
63
|
+
.header__button {
|
|
64
|
+
margin-top: 0;
|
|
65
|
+
}
|
|
66
|
+
.header__logo {
|
|
67
|
+
margin: 0 32px 0 0;
|
|
68
|
+
cursor: pointer;
|
|
69
|
+
}
|
|
70
|
+
@media (max-width: 768px) {
|
|
71
|
+
.header__navigation-container {
|
|
72
|
+
justify-content: flex-end;
|
|
73
|
+
}
|
|
74
|
+
.header__left {
|
|
75
|
+
flex: 1 0 0;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
@media (max-width: 576px) {
|
|
79
|
+
.header__navigation-container {
|
|
80
|
+
margin-right: 12px;
|
|
81
|
+
}
|
|
82
|
+
.header__logo {
|
|
83
|
+
margin-right: 0;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { HeaderData, NavigationLogo } from '../../../../models/navigation';
|
|
3
|
+
export interface HeaderProps {
|
|
4
|
+
logo: NavigationLogo;
|
|
5
|
+
data: HeaderData;
|
|
6
|
+
}
|
|
7
|
+
interface HeaderState {
|
|
8
|
+
isSidebarOpened: boolean;
|
|
9
|
+
activeItemIndex: number;
|
|
10
|
+
}
|
|
11
|
+
declare class Header extends React.Component<HeaderProps, HeaderState> {
|
|
12
|
+
ref: React.RefObject<unknown>;
|
|
13
|
+
state: {
|
|
14
|
+
isSidebarOpened: boolean;
|
|
15
|
+
activeItemIndex: number;
|
|
16
|
+
};
|
|
17
|
+
render(): JSX.Element;
|
|
18
|
+
private renderLeft;
|
|
19
|
+
private renderLogo;
|
|
20
|
+
private renderRight;
|
|
21
|
+
private renderRightItems;
|
|
22
|
+
private renderMobileMenuButton;
|
|
23
|
+
private renderMobileNavigation;
|
|
24
|
+
private onActiveItemChange;
|
|
25
|
+
private onSidebarOpenedChange;
|
|
26
|
+
private hideSidebar;
|
|
27
|
+
}
|
|
28
|
+
export default Header;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const react_1 = (0, tslib_1.__importStar)(require("react"));
|
|
5
|
+
const bem_cn_lite_1 = (0, tslib_1.__importDefault)(require("bem-cn-lite"));
|
|
6
|
+
const grid_1 = require("../../../../grid");
|
|
7
|
+
const OutsideClick_1 = (0, tslib_1.__importDefault)(require("../../../OutsideClick/OutsideClick"));
|
|
8
|
+
const Control_1 = (0, tslib_1.__importDefault)(require("../../../Control/Control"));
|
|
9
|
+
const Logo_1 = (0, tslib_1.__importDefault)(require("../Logo/Logo"));
|
|
10
|
+
const Navigation_1 = (0, tslib_1.__importDefault)(require("../Navigation/Navigation"));
|
|
11
|
+
const MobileNavigation_1 = (0, tslib_1.__importDefault)(require("../MobileNavigation/MobileNavigation"));
|
|
12
|
+
const NavigationItem_1 = (0, tslib_1.__importDefault)(require("../NavigationItem/NavigationItem"));
|
|
13
|
+
const icons_1 = require("../../../../icons");
|
|
14
|
+
const b = (0, bem_cn_lite_1.default)('header');
|
|
15
|
+
class Header extends react_1.default.Component {
|
|
16
|
+
constructor() {
|
|
17
|
+
super(...arguments);
|
|
18
|
+
this.ref = (0, react_1.createRef)();
|
|
19
|
+
this.state = {
|
|
20
|
+
isSidebarOpened: false,
|
|
21
|
+
activeItemIndex: -1,
|
|
22
|
+
};
|
|
23
|
+
this.onActiveItemChange = (index) => {
|
|
24
|
+
this.setState({ activeItemIndex: index });
|
|
25
|
+
};
|
|
26
|
+
this.onSidebarOpenedChange = (isSidebarOpened) => {
|
|
27
|
+
this.setState({ isSidebarOpened });
|
|
28
|
+
};
|
|
29
|
+
this.hideSidebar = () => {
|
|
30
|
+
this.setState({ isSidebarOpened: false });
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
render() {
|
|
34
|
+
return (react_1.default.createElement(grid_1.Grid, { className: b() },
|
|
35
|
+
react_1.default.createElement(grid_1.Row, null,
|
|
36
|
+
react_1.default.createElement(grid_1.Col, null,
|
|
37
|
+
react_1.default.createElement("header", { className: b('wrapper') },
|
|
38
|
+
this.renderLogo(),
|
|
39
|
+
this.renderLeft(),
|
|
40
|
+
this.renderRight(),
|
|
41
|
+
this.renderMobileNavigation())))));
|
|
42
|
+
}
|
|
43
|
+
renderLeft() {
|
|
44
|
+
const { activeItemIndex } = this.state;
|
|
45
|
+
const { leftItems } = this.props.data;
|
|
46
|
+
return (leftItems && (react_1.default.createElement("div", { className: b('navigation-container') },
|
|
47
|
+
react_1.default.createElement(Navigation_1.default, { className: b('navigation'), links: leftItems, activeItemIndex: activeItemIndex, onActiveItemChange: this.onActiveItemChange }))));
|
|
48
|
+
}
|
|
49
|
+
renderLogo() {
|
|
50
|
+
const { logo } = this.props;
|
|
51
|
+
if (!logo) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
return (react_1.default.createElement("div", { className: b('left') },
|
|
55
|
+
react_1.default.createElement(Logo_1.default, Object.assign({}, logo, { className: b('logo') }))));
|
|
56
|
+
}
|
|
57
|
+
renderRight() {
|
|
58
|
+
return (react_1.default.createElement("div", { className: b('right') },
|
|
59
|
+
this.renderMobileMenuButton(),
|
|
60
|
+
this.renderRightItems()));
|
|
61
|
+
}
|
|
62
|
+
renderRightItems() {
|
|
63
|
+
const { rightItems } = this.props.data;
|
|
64
|
+
return (rightItems && (react_1.default.createElement("div", { className: b('buttons') }, rightItems.map((button) => (react_1.default.createElement(NavigationItem_1.default, { key: button.text, data: button, className: b('button') }))))));
|
|
65
|
+
}
|
|
66
|
+
renderMobileMenuButton() {
|
|
67
|
+
const { isSidebarOpened } = this.state;
|
|
68
|
+
const iconProps = { icon: isSidebarOpened ? icons_1.NavigationClose : icons_1.NavigationOpen, iconSize: 36 };
|
|
69
|
+
return (react_1.default.createElement(Control_1.default, Object.assign({ className: b('mobile-menu-button'), onClick: (e) => {
|
|
70
|
+
e.stopPropagation();
|
|
71
|
+
this.onSidebarOpenedChange(!isSidebarOpened);
|
|
72
|
+
}, size: "l" }, iconProps)));
|
|
73
|
+
}
|
|
74
|
+
renderMobileNavigation() {
|
|
75
|
+
const { leftItems, rightItems } = this.props.data;
|
|
76
|
+
const { isSidebarOpened, activeItemIndex } = this.state;
|
|
77
|
+
return (react_1.default.createElement(OutsideClick_1.default, { onOutsideClick: () => this.onSidebarOpenedChange(false) },
|
|
78
|
+
react_1.default.createElement(MobileNavigation_1.default, { topItems: leftItems, bottomItems: rightItems, isOpened: isSidebarOpened, activeItemIndex: activeItemIndex, onActiveItemChange: this.onActiveItemChange, onClose: this.hideSidebar })));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.default = Header;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/* use this for style redefinitions to awoid problems with
|
|
2
|
+
unpredictable css rules order in build */
|
|
3
|
+
.logo {
|
|
4
|
+
display: flex;
|
|
5
|
+
align-items: center;
|
|
6
|
+
font-weight: 500;
|
|
7
|
+
font-size: var(--yc-text-header-2-font-size);
|
|
8
|
+
line-height: var(--yc-text-header-2-line-height);
|
|
9
|
+
}
|
|
10
|
+
.logo__icon {
|
|
11
|
+
width: 178px;
|
|
12
|
+
height: 36px;
|
|
13
|
+
margin-right: 8px;
|
|
14
|
+
object-fit: contain;
|
|
15
|
+
}
|
|
16
|
+
.logo__text {
|
|
17
|
+
white-space: nowrap;
|
|
18
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const react_1 = (0, tslib_1.__importDefault)(require("react"));
|
|
5
|
+
const bem_cn_lite_1 = (0, tslib_1.__importDefault)(require("bem-cn-lite"));
|
|
6
|
+
const index_1 = require("../../../index");
|
|
7
|
+
const RouterLink_1 = (0, tslib_1.__importDefault)(require("../../../RouterLink/RouterLink"));
|
|
8
|
+
const b = (0, bem_cn_lite_1.default)('logo');
|
|
9
|
+
const Logo = ({ icon, text, className }) => (react_1.default.createElement(RouterLink_1.default, { href: "/", passHref: true },
|
|
10
|
+
react_1.default.createElement("div", { className: b(null, className) },
|
|
11
|
+
icon && react_1.default.createElement(index_1.Image, { className: b('icon'), src: icon }),
|
|
12
|
+
react_1.default.createElement("span", { className: b('text') }, text))));
|
|
13
|
+
exports.default = Logo;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/* use this for style redefinitions to awoid problems with
|
|
2
|
+
unpredictable css rules order in build */
|
|
3
|
+
.mobile-navigation {
|
|
4
|
+
position: fixed;
|
|
5
|
+
z-index: 100;
|
|
6
|
+
top: var(--header-height);
|
|
7
|
+
left: 0;
|
|
8
|
+
width: 100%;
|
|
9
|
+
border-bottom-right-radius: var(--pc-border-radius);
|
|
10
|
+
border-bottom-left-radius: var(--pc-border-radius);
|
|
11
|
+
background-color: var(--yc-color-base-background);
|
|
12
|
+
box-shadow: 0px 3px 10px var(--yc-color-sfx-shadow);
|
|
13
|
+
font-size: var(--yc-text-body-2-font-size);
|
|
14
|
+
line-height: var(--yc-text-body-2-line-height);
|
|
15
|
+
}
|
|
16
|
+
@media (min-width: 769px) {
|
|
17
|
+
.mobile-navigation {
|
|
18
|
+
display: none;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
.mobile-navigation__wrapper {
|
|
22
|
+
padding: 32px 20px;
|
|
23
|
+
}
|
|
24
|
+
.mobile-navigation__button {
|
|
25
|
+
margin-top: 24px;
|
|
26
|
+
}
|
|
27
|
+
.mobile-navigation__links {
|
|
28
|
+
position: relative;
|
|
29
|
+
display: flex;
|
|
30
|
+
flex-direction: column;
|
|
31
|
+
padding-bottom: 24px;
|
|
32
|
+
margin: 0;
|
|
33
|
+
padding: 0;
|
|
34
|
+
list-style: none;
|
|
35
|
+
}
|
|
36
|
+
.mobile-navigation__links-item:not(:last-child) {
|
|
37
|
+
margin-bottom: 24px;
|
|
38
|
+
}
|
|
39
|
+
.mobile-navigation__dropdown-item:not(:last-child) {
|
|
40
|
+
margin-bottom: 16px;
|
|
41
|
+
}
|
|
42
|
+
.mobile-navigation__popup {
|
|
43
|
+
z-index: 101;
|
|
44
|
+
display: flex;
|
|
45
|
+
flex-direction: column;
|
|
46
|
+
min-width: 220px;
|
|
47
|
+
padding: 16px;
|
|
48
|
+
border: 1px solid var(--yc-color-line-generic);
|
|
49
|
+
border-top-width: 0;
|
|
50
|
+
border-radius: calc(var(--pc-border-radius) / 2);
|
|
51
|
+
background: var(--yc-color-base-float);
|
|
52
|
+
box-shadow: 0 3px 10px var(--yc-color-sfx-shadow);
|
|
53
|
+
}
|
|
54
|
+
@media (min-width: 769px) {
|
|
55
|
+
.mobile-navigation__popup {
|
|
56
|
+
display: none;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { NavigationItem as NavigationItemModel } from '../../../../models/navigation';
|
|
3
|
+
export interface MobileNavigationProps {
|
|
4
|
+
className?: string;
|
|
5
|
+
isOpened?: boolean;
|
|
6
|
+
topItems?: NavigationItemModel[];
|
|
7
|
+
bottomItems?: NavigationItemModel[];
|
|
8
|
+
activeItemIndex: number;
|
|
9
|
+
onClose: () => void;
|
|
10
|
+
onActiveItemChange: (index: number) => void;
|
|
11
|
+
}
|
|
12
|
+
declare const MobileNavigation: React.FC<MobileNavigationProps>;
|
|
13
|
+
export default MobileNavigation;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const bem_cn_lite_1 = (0, tslib_1.__importDefault)(require("bem-cn-lite"));
|
|
5
|
+
const react_1 = (0, tslib_1.__importStar)(require("react"));
|
|
6
|
+
const Foldable_1 = (0, tslib_1.__importDefault)(require("../../../Foldable/Foldable"));
|
|
7
|
+
const uikit_1 = require("@gravity-ui/uikit");
|
|
8
|
+
const navigation_1 = require("../../../../models/navigation");
|
|
9
|
+
const NavigationItem_1 = (0, tslib_1.__importDefault)(require("../NavigationItem/NavigationItem"));
|
|
10
|
+
const b = (0, bem_cn_lite_1.default)('mobile-navigation');
|
|
11
|
+
const MobileNavigationDropdown = ({ data, onItemClick, onToggle, isOpened = false, }) => {
|
|
12
|
+
const ref = (0, react_1.useRef)(null);
|
|
13
|
+
return (react_1.default.createElement("div", { ref: ref, className: b('dropdown') },
|
|
14
|
+
react_1.default.createElement(NavigationItem_1.default, { data: data, onClick: onToggle, isOpened: isOpened }),
|
|
15
|
+
isOpened && (react_1.default.createElement(uikit_1.Popup, { anchorRef: ref, open: isOpened, className: b('popup') }, data.items.map((item) => (react_1.default.createElement(NavigationItem_1.default, { key: item.text, data: item, className: b('dropdown-item'), onClick: onItemClick })))))));
|
|
16
|
+
};
|
|
17
|
+
const MobileNavigationItem = ({ link, index, isActive, onActiveItemChange, onClose, }) => {
|
|
18
|
+
const toggleActive = (0, react_1.useCallback)((e) => {
|
|
19
|
+
e.stopPropagation();
|
|
20
|
+
if (onActiveItemChange) {
|
|
21
|
+
onActiveItemChange(isActive ? -1 : index);
|
|
22
|
+
}
|
|
23
|
+
}, [isActive, index, onActiveItemChange]);
|
|
24
|
+
const onItemClick = (0, react_1.useCallback)((e) => {
|
|
25
|
+
toggleActive(e);
|
|
26
|
+
onClose();
|
|
27
|
+
}, [toggleActive, onClose]);
|
|
28
|
+
return (react_1.default.createElement("li", { key: index, className: b('links-item') }, link.type === navigation_1.NavigationItemType.Dropdown ? (react_1.default.createElement(MobileNavigationDropdown, { data: link, onToggle: toggleActive, isOpened: isActive, onItemClick: onItemClick })) : (react_1.default.createElement(NavigationItem_1.default, { data: link, onClick: onItemClick }))));
|
|
29
|
+
};
|
|
30
|
+
const MobileNavigation = (props) => {
|
|
31
|
+
if (typeof window === 'undefined') {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
const { isOpened, topItems, bottomItems, activeItemIndex, onActiveItemChange, onClose } = props;
|
|
35
|
+
return (react_1.default.createElement(uikit_1.Portal, null,
|
|
36
|
+
react_1.default.createElement(Foldable_1.default, { key: topItems === null || topItems === void 0 ? void 0 : topItems.length, className: b(), isOpened: Boolean(isOpened) },
|
|
37
|
+
react_1.default.createElement("div", { className: b('wrapper') },
|
|
38
|
+
react_1.default.createElement("nav", null,
|
|
39
|
+
react_1.default.createElement("ul", { className: b('links') }, topItems === null || topItems === void 0 ? void 0 : topItems.map((link, index) => {
|
|
40
|
+
const isActive = index === activeItemIndex;
|
|
41
|
+
return (react_1.default.createElement(MobileNavigationItem, { key: index, link: link, index: index, isActive: isOpened && isActive, onClose: onClose, onActiveItemChange: onActiveItemChange }));
|
|
42
|
+
}))), bottomItems === null || bottomItems === void 0 ? void 0 :
|
|
43
|
+
bottomItems.map((item) => (react_1.default.createElement(NavigationItem_1.default, { key: item.text, data: item, className: b('button') })))))));
|
|
44
|
+
};
|
|
45
|
+
exports.default = MobileNavigation;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/* use this for style redefinitions to awoid problems with
|
|
2
|
+
unpredictable css rules order in build */
|
|
3
|
+
.navigation {
|
|
4
|
+
font-size: var(--yc-text-body-2-font-size);
|
|
5
|
+
line-height: var(--yc-text-body-2-line-height);
|
|
6
|
+
}
|
|
7
|
+
.navigation__links {
|
|
8
|
+
position: relative;
|
|
9
|
+
display: flex;
|
|
10
|
+
align-items: center;
|
|
11
|
+
margin: 0;
|
|
12
|
+
padding: 0;
|
|
13
|
+
list-style: none;
|
|
14
|
+
}
|
|
15
|
+
.navigation__links-item {
|
|
16
|
+
position: relative;
|
|
17
|
+
height: var(--header-height);
|
|
18
|
+
line-height: var(--header-height);
|
|
19
|
+
cursor: pointer;
|
|
20
|
+
outline: none;
|
|
21
|
+
color: inherit;
|
|
22
|
+
text-decoration: none;
|
|
23
|
+
}
|
|
24
|
+
.utilityfocus .navigation__links-item:focus {
|
|
25
|
+
outline: 2px solid #ffdb4d;
|
|
26
|
+
}
|
|
27
|
+
.navigation__links-item:hover, .navigation__links-item:active {
|
|
28
|
+
color: var(--yc-color-text-link);
|
|
29
|
+
}
|
|
30
|
+
.navigation__links-item:not(:last-child) {
|
|
31
|
+
margin-right: 20px;
|
|
32
|
+
}
|
|
33
|
+
.navigation__slider-container {
|
|
34
|
+
position: absolute;
|
|
35
|
+
right: 0;
|
|
36
|
+
bottom: 0;
|
|
37
|
+
left: 0;
|
|
38
|
+
}
|
|
39
|
+
.navigation__slider {
|
|
40
|
+
width: 100%;
|
|
41
|
+
height: 2px;
|
|
42
|
+
background-color: var(--yc-color-text-link);
|
|
43
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { NavigationItem as NavigationItemModel } from '../../../../models/navigation';
|
|
3
|
+
export interface NavigationProps {
|
|
4
|
+
links: NavigationItemModel[];
|
|
5
|
+
activeItemIndex: number;
|
|
6
|
+
onActiveItemChange: (index: number) => void;
|
|
7
|
+
className?: string;
|
|
8
|
+
highlightActiveItem?: boolean;
|
|
9
|
+
}
|
|
10
|
+
declare const Navigation: React.FC<NavigationProps>;
|
|
11
|
+
export default Navigation;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const lodash_1 = (0, tslib_1.__importDefault)(require("lodash"));
|
|
5
|
+
const bem_cn_lite_1 = (0, tslib_1.__importDefault)(require("bem-cn-lite"));
|
|
6
|
+
const react_1 = (0, tslib_1.__importStar)(require("react"));
|
|
7
|
+
const OverflowScroller_1 = (0, tslib_1.__importDefault)(require("../../../OverflowScroller/OverflowScroller"));
|
|
8
|
+
const navigation_1 = require("../../../../models/navigation");
|
|
9
|
+
const NavigationPopup_1 = (0, tslib_1.__importDefault)(require("../NavigationPopup/NavigationPopup"));
|
|
10
|
+
const NavigationItem_1 = (0, tslib_1.__importDefault)(require("../NavigationItem/NavigationItem"));
|
|
11
|
+
const locationContext_1 = require("../../../../context/locationContext");
|
|
12
|
+
const b = (0, bem_cn_lite_1.default)('navigation');
|
|
13
|
+
const Navigation = ({ className, onActiveItemChange, links, activeItemIndex, highlightActiveItem, }) => {
|
|
14
|
+
const { asPath, pathname } = (0, react_1.useContext)(locationContext_1.LocationContext);
|
|
15
|
+
const itemRefs = (0, react_1.useRef)([]);
|
|
16
|
+
const [itemPositions, setItemPosition] = (0, react_1.useState)([]);
|
|
17
|
+
const [lastLeftScroll, setLastLeftScroll] = (0, react_1.useState)(0);
|
|
18
|
+
const hidePopup = (0, react_1.useCallback)(() => {
|
|
19
|
+
onActiveItemChange(-1);
|
|
20
|
+
}, [onActiveItemChange]);
|
|
21
|
+
const getItemClickHandler = (0, react_1.useCallback)((index) => (e) => {
|
|
22
|
+
e.stopPropagation();
|
|
23
|
+
onActiveItemChange(index === activeItemIndex ? -1 : index);
|
|
24
|
+
}, [activeItemIndex, onActiveItemChange]);
|
|
25
|
+
const renderNavDropdown = (data, onClick, isActive, position) => {
|
|
26
|
+
const { text, items } = data, popupProps = (0, tslib_1.__rest)(data, ["text", "items"]);
|
|
27
|
+
return (react_1.default.createElement(react_1.Fragment, null,
|
|
28
|
+
react_1.default.createElement(NavigationItem_1.default, { className: b('link'), onClick: onClick, isOpened: isActive, data: { text, type: navigation_1.NavigationItemType.Dropdown } }),
|
|
29
|
+
isActive && (react_1.default.createElement(NavigationPopup_1.default, Object.assign({ left: position, onClose: hidePopup, items: items }, popupProps)))));
|
|
30
|
+
};
|
|
31
|
+
const slider = (react_1.default.createElement("div", { className: b('slider-container') },
|
|
32
|
+
react_1.default.createElement("div", { className: b('slider') })));
|
|
33
|
+
const content = (react_1.default.createElement("nav", null,
|
|
34
|
+
react_1.default.createElement("ul", { className: b('links') }, links.map((link, index) => {
|
|
35
|
+
const isActive = index === activeItemIndex;
|
|
36
|
+
const onClick = getItemClickHandler(index);
|
|
37
|
+
return (react_1.default.createElement("li", { ref: (el) => itemRefs.current.push(el), key: index, className: b('links-item') },
|
|
38
|
+
link.type === navigation_1.NavigationItemType.Dropdown ? (renderNavDropdown(link, onClick, isActive, itemPositions[index])) : (react_1.default.createElement(NavigationItem_1.default, { data: link, onClick: onClick })),
|
|
39
|
+
highlightActiveItem && isActive && slider));
|
|
40
|
+
}))));
|
|
41
|
+
const calculateItemPositions = (0, react_1.useCallback)(() => {
|
|
42
|
+
if (itemRefs.current.length) {
|
|
43
|
+
const currentItemPositions = itemRefs.current.map((itemRef) => (itemRef && itemRef.getBoundingClientRect().left) || 0);
|
|
44
|
+
setItemPosition(currentItemPositions);
|
|
45
|
+
}
|
|
46
|
+
}, []);
|
|
47
|
+
(0, react_1.useEffect)(() => {
|
|
48
|
+
const debouncedCalculateItemPositions = lodash_1.default.debounce(calculateItemPositions, 100);
|
|
49
|
+
const calculateOnScroll = lodash_1.default.debounce(() => {
|
|
50
|
+
const curLeftScroll = window.pageXOffset;
|
|
51
|
+
if (curLeftScroll !== lastLeftScroll) {
|
|
52
|
+
setLastLeftScroll(window.pageXOffset);
|
|
53
|
+
calculateItemPositions();
|
|
54
|
+
}
|
|
55
|
+
}, 100);
|
|
56
|
+
calculateItemPositions();
|
|
57
|
+
setLastLeftScroll(window.pageXOffset);
|
|
58
|
+
window.addEventListener('resize', debouncedCalculateItemPositions);
|
|
59
|
+
window.addEventListener('scroll', calculateOnScroll);
|
|
60
|
+
return () => {
|
|
61
|
+
window.removeEventListener(`resize`, calculateItemPositions);
|
|
62
|
+
window.removeEventListener('scroll', calculateOnScroll);
|
|
63
|
+
};
|
|
64
|
+
}, [calculateItemPositions, itemRefs, lastLeftScroll]);
|
|
65
|
+
(0, react_1.useEffect)(() => {
|
|
66
|
+
hidePopup();
|
|
67
|
+
}, [hidePopup, asPath, pathname]);
|
|
68
|
+
return (react_1.default.createElement(OverflowScroller_1.default, { className: b(null, className), onScrollStart: hidePopup, onScrollEnd: calculateItemPositions }, content));
|
|
69
|
+
};
|
|
70
|
+
exports.default = Navigation;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/* use this for style redefinitions to awoid problems with
|
|
2
|
+
unpredictable css rules order in build */
|
|
3
|
+
.navigation-item {
|
|
4
|
+
position: relative;
|
|
5
|
+
display: flex;
|
|
6
|
+
align-items: center;
|
|
7
|
+
}
|
|
8
|
+
.navigation-item_type_link {
|
|
9
|
+
color: var(--yc-color-text-primary);
|
|
10
|
+
color: inherit;
|
|
11
|
+
text-decoration: none;
|
|
12
|
+
outline: none;
|
|
13
|
+
}
|
|
14
|
+
.utilityfocus .navigation-item_type_link:focus {
|
|
15
|
+
outline: 2px solid #ffdb4d;
|
|
16
|
+
}
|
|
17
|
+
.navigation-item_type_link:hover, .navigation-item_type_link_active {
|
|
18
|
+
color: var(--yc-color-text-link);
|
|
19
|
+
}
|
|
20
|
+
.navigation-item_type_button {
|
|
21
|
+
display: inline-block;
|
|
22
|
+
}
|
|
23
|
+
.navigation-item__arrow {
|
|
24
|
+
position: relative;
|
|
25
|
+
top: -2px;
|
|
26
|
+
width: 9px;
|
|
27
|
+
height: 9px;
|
|
28
|
+
margin-left: 5px;
|
|
29
|
+
}
|
|
30
|
+
.navigation-item__icon {
|
|
31
|
+
width: 20px;
|
|
32
|
+
height: 20px;
|
|
33
|
+
margin-right: 8px;
|
|
34
|
+
border-radius: 50%;
|
|
35
|
+
object-fit: cover;
|
|
36
|
+
}
|
|
37
|
+
.navigation-item__dropdown {
|
|
38
|
+
margin-left: 7px;
|
|
39
|
+
color: var(--yc-color-text-secondary);
|
|
40
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React, { MouseEventHandler } from 'react';
|
|
2
|
+
import { NavigationButtonItem, NavigationDropdownItem, NavigationSocialItem, NavigationLinkItem } from '../../../../models/navigation';
|
|
3
|
+
declare type DropdownItemData = Omit<NavigationDropdownItem, 'items'>;
|
|
4
|
+
export declare type NavigationItemData = NavigationLinkItem | NavigationButtonItem | NavigationSocialItem | DropdownItemData;
|
|
5
|
+
export interface NavigationItemProps {
|
|
6
|
+
data: NavigationItemData;
|
|
7
|
+
className?: string;
|
|
8
|
+
onClick?: MouseEventHandler;
|
|
9
|
+
isOpened?: boolean;
|
|
10
|
+
}
|
|
11
|
+
declare const NavigationItem: React.FC<NavigationItemProps>;
|
|
12
|
+
export default NavigationItem;
|