@gravity-ui/page-constructor 1.7.0-alpha.7 → 1.7.0-alpha.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/README.md +58 -36
  2. package/build/cjs/blocks/Tabs/Tabs.css +23 -49
  3. package/build/cjs/blocks/Tabs/Tabs.d.ts +1 -1
  4. package/build/cjs/blocks/Tabs/Tabs.js +27 -29
  5. package/build/cjs/components/Image/Image.js +1 -3
  6. package/build/cjs/components/OverflowScroller/OverflowScroller.css +2 -0
  7. package/build/cjs/components/RouterLink/RouterLink.d.ts +1 -0
  8. package/build/cjs/components/VideoBlock/VideoBlock.js +1 -1
  9. package/build/cjs/components/index.d.ts +2 -0
  10. package/build/cjs/components/index.js +40 -39
  11. package/build/cjs/components/navigation/components/Header/Header.css +85 -0
  12. package/build/cjs/components/navigation/components/Header/Header.d.ts +8 -0
  13. package/build/cjs/components/navigation/components/Header/Header.js +51 -0
  14. package/build/cjs/components/navigation/components/Logo/Logo.css +23 -0
  15. package/build/cjs/components/navigation/components/Logo/Logo.d.ts +7 -0
  16. package/build/cjs/components/navigation/components/Logo/Logo.js +17 -0
  17. package/build/cjs/components/navigation/components/MobileNavigation/MobileNavigation.css +58 -0
  18. package/build/cjs/components/navigation/components/MobileNavigation/MobileNavigation.d.ts +13 -0
  19. package/build/cjs/components/navigation/components/MobileNavigation/MobileNavigation.js +45 -0
  20. package/build/cjs/components/navigation/components/Navigation/Navigation.css +43 -0
  21. package/build/cjs/components/navigation/components/Navigation/Navigation.d.ts +18 -0
  22. package/build/cjs/components/navigation/components/Navigation/Navigation.js +71 -0
  23. package/build/cjs/components/navigation/components/NavigationItem/NavigationItem.css +41 -0
  24. package/build/cjs/components/navigation/components/NavigationItem/NavigationItem.d.ts +12 -0
  25. package/build/cjs/components/navigation/components/NavigationItem/NavigationItem.js +60 -0
  26. package/build/cjs/components/navigation/components/NavigationPopup/NavigationPopup.css +33 -0
  27. package/build/cjs/components/navigation/components/NavigationPopup/NavigationPopup.d.ts +10 -0
  28. package/build/cjs/components/navigation/components/NavigationPopup/NavigationPopup.js +45 -0
  29. package/build/cjs/components/navigation/components/SocialIcon/SocialIcon.css +20 -0
  30. package/build/cjs/components/navigation/components/SocialIcon/SocialIcon.d.ts +7 -0
  31. package/build/cjs/components/navigation/components/SocialIcon/SocialIcon.js +14 -0
  32. package/build/cjs/components/navigation/components/index.d.ts +7 -0
  33. package/build/cjs/components/navigation/components/index.js +20 -0
  34. package/build/cjs/components/navigation/containers/Layout/Layout.css +10 -0
  35. package/build/cjs/components/navigation/containers/Layout/Layout.d.ts +7 -0
  36. package/build/cjs/components/navigation/containers/Layout/Layout.js +11 -0
  37. package/build/cjs/constructor-items.d.ts +1 -1
  38. package/build/cjs/containers/PageConstructor/PageConstructor.d.ts +3 -2
  39. package/build/cjs/containers/PageConstructor/PageConstructor.js +12 -10
  40. package/build/cjs/context/locationContext/locationContext.d.ts +1 -0
  41. package/build/cjs/icons/NavigationArrow.d.ts +2 -0
  42. package/build/cjs/icons/NavigationArrow.js +9 -0
  43. package/build/cjs/icons/NavigationClose.d.ts +2 -0
  44. package/build/cjs/icons/NavigationClose.js +9 -0
  45. package/build/cjs/icons/NavigationOpen.d.ts +2 -0
  46. package/build/cjs/icons/NavigationOpen.js +11 -0
  47. package/build/cjs/icons/index.d.ts +3 -0
  48. package/build/cjs/icons/index.js +3 -0
  49. package/build/cjs/models/constructor-items/blocks.d.ts +4 -7
  50. package/build/cjs/models/index.d.ts +1 -0
  51. package/build/cjs/models/index.js +1 -0
  52. package/build/cjs/models/navigation.d.ts +60 -0
  53. package/build/cjs/models/navigation.js +10 -0
  54. package/build/cjs/text-transform/blocks.js +4 -11
  55. package/build/cjs/text-transform/utils.js +1 -1
  56. package/build/esm/blocks/Tabs/Tabs.css +23 -49
  57. package/build/esm/blocks/Tabs/Tabs.d.ts +1 -1
  58. package/build/esm/blocks/Tabs/Tabs.js +27 -29
  59. package/build/esm/components/Image/Image.d.ts +0 -1
  60. package/build/esm/components/Image/Image.js +1 -4
  61. package/build/esm/components/OverflowScroller/OverflowScroller.css +2 -0
  62. package/build/esm/components/RouterLink/RouterLink.d.ts +1 -0
  63. package/build/esm/components/VideoBlock/VideoBlock.js +1 -1
  64. package/build/esm/components/index.d.ts +2 -0
  65. package/build/esm/components/index.js +2 -0
  66. package/build/esm/components/navigation/components/Header/Header.css +85 -0
  67. package/build/esm/components/navigation/components/Header/Header.d.ts +9 -0
  68. package/build/esm/components/navigation/components/Header/Header.js +47 -0
  69. package/build/esm/components/navigation/components/Logo/Logo.css +23 -0
  70. package/build/esm/components/navigation/components/Logo/Logo.d.ts +8 -0
  71. package/build/esm/components/navigation/components/Logo/Logo.js +15 -0
  72. package/build/esm/components/navigation/components/MobileNavigation/MobileNavigation.css +58 -0
  73. package/build/esm/components/navigation/components/MobileNavigation/MobileNavigation.d.ts +14 -0
  74. package/build/esm/components/navigation/components/MobileNavigation/MobileNavigation.js +43 -0
  75. package/build/esm/components/navigation/components/Navigation/Navigation.css +43 -0
  76. package/build/esm/components/navigation/components/Navigation/Navigation.d.ts +19 -0
  77. package/build/esm/components/navigation/components/Navigation/Navigation.js +70 -0
  78. package/build/esm/components/navigation/components/NavigationItem/NavigationItem.css +41 -0
  79. package/build/esm/components/navigation/components/NavigationItem/NavigationItem.d.ts +13 -0
  80. package/build/esm/components/navigation/components/NavigationItem/NavigationItem.js +59 -0
  81. package/build/esm/components/navigation/components/NavigationPopup/NavigationPopup.css +33 -0
  82. package/build/esm/components/navigation/components/NavigationPopup/NavigationPopup.d.ts +11 -0
  83. package/build/esm/components/navigation/components/NavigationPopup/NavigationPopup.js +41 -0
  84. package/build/esm/components/navigation/components/SocialIcon/SocialIcon.css +20 -0
  85. package/build/esm/components/navigation/components/SocialIcon/SocialIcon.d.ts +8 -0
  86. package/build/esm/components/navigation/components/SocialIcon/SocialIcon.js +12 -0
  87. package/build/esm/components/navigation/components/index.d.ts +7 -0
  88. package/build/esm/components/navigation/components/index.js +7 -0
  89. package/build/esm/components/navigation/containers/Layout/Layout.css +10 -0
  90. package/build/esm/components/navigation/containers/Layout/Layout.d.ts +8 -0
  91. package/build/esm/components/navigation/containers/Layout/Layout.js +9 -0
  92. package/build/esm/constructor-items.d.ts +1 -1
  93. package/build/esm/containers/PageConstructor/PageConstructor.d.ts +3 -2
  94. package/build/esm/containers/PageConstructor/PageConstructor.js +12 -10
  95. package/build/esm/context/locationContext/locationContext.d.ts +1 -0
  96. package/build/esm/icons/NavigationArrow.d.ts +2 -0
  97. package/build/esm/icons/NavigationArrow.js +4 -0
  98. package/build/esm/icons/NavigationClose.d.ts +2 -0
  99. package/build/esm/icons/NavigationClose.js +4 -0
  100. package/build/esm/icons/NavigationOpen.d.ts +2 -0
  101. package/build/esm/icons/NavigationOpen.js +6 -0
  102. package/build/esm/icons/index.d.ts +3 -0
  103. package/build/esm/icons/index.js +3 -0
  104. package/build/esm/models/constructor-items/blocks.d.ts +4 -7
  105. package/build/esm/models/index.d.ts +1 -0
  106. package/build/esm/models/index.js +1 -0
  107. package/build/esm/models/navigation.d.ts +60 -0
  108. package/build/esm/models/navigation.js +7 -0
  109. package/build/esm/text-transform/blocks.js +4 -11
  110. package/build/esm/text-transform/utils.js +1 -1
  111. package/package.json +1 -4
  112. package/server/models/constructor-items/blocks.d.ts +4 -7
  113. package/server/models/index.d.ts +1 -0
  114. package/server/models/index.js +1 -0
  115. package/server/models/navigation.d.ts +60 -0
  116. package/server/models/navigation.js +10 -0
  117. package/server/text-transform/blocks.js +4 -11
  118. package/server/text-transform/utils.js +1 -1
  119. package/styles/mixins.scss +38 -0
  120. package/build/cjs/components/ButtonTabs/ButtonTabs.css +0 -12
  121. package/build/cjs/components/ButtonTabs/ButtonTabs.d.ts +0 -13
  122. package/build/cjs/components/ButtonTabs/ButtonTabs.js +0 -27
  123. package/build/cjs/components/Image/Image.css +0 -3
  124. package/build/esm/components/ButtonTabs/ButtonTabs.css +0 -12
  125. package/build/esm/components/ButtonTabs/ButtonTabs.d.ts +0 -14
  126. package/build/esm/components/ButtonTabs/ButtonTabs.js +0 -25
  127. package/build/esm/components/Image/Image.css +0 -3
@@ -33,4 +33,6 @@ export { default as OverflowScroller } from './OverflowScroller/OverflowScroller
33
33
  export { default as Author } from './Author/Author';
34
34
  export { default as RouterLink } from './RouterLink/RouterLink';
35
35
  export { default as HTML } from './HTML/HTML';
36
+ export { default as Header } from './navigation/components/Header/Header';
37
+ export * as Navigation from './navigation/components/index';
36
38
  export type { RouterLinkProps } from './RouterLink/RouterLink';
@@ -33,3 +33,5 @@ export { default as OverflowScroller } from './OverflowScroller/OverflowScroller
33
33
  export { default as Author } from './Author/Author';
34
34
  export { default as RouterLink } from './RouterLink/RouterLink';
35
35
  export { default as HTML } from './HTML/HTML';
36
+ export { default as Header } from './navigation/components/Header/Header';
37
+ export * as Navigation from './navigation/components/index';
@@ -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 0 -1px 0 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
+ margin-right: 20px;
32
+ flex: 1 0 0;
33
+ justify-content: flex-start;
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,9 @@
1
+ import React from 'react';
2
+ import { HeaderData, NavigationLogo } from '../../../../models';
3
+ import './Header.css';
4
+ export interface HeaderProps {
5
+ logo: NavigationLogo;
6
+ data: HeaderData;
7
+ }
8
+ export declare const Header: React.FC<HeaderProps>;
9
+ export default Header;
@@ -0,0 +1,47 @@
1
+ import React, { useCallback, useState } from 'react';
2
+ import block from 'bem-cn-lite';
3
+ import { Col, Grid, Row } from '../../../../grid';
4
+ import OutsideClick from '../../../OutsideClick/OutsideClick';
5
+ import Control from '../../../Control/Control';
6
+ import Navigation from '../Navigation/Navigation';
7
+ import MobileNavigation from '../MobileNavigation/MobileNavigation';
8
+ import NavigationItem from '../NavigationItem/NavigationItem';
9
+ import Logo from '../Logo/Logo';
10
+ import { NavigationClose, NavigationOpen } from '../../../../icons';
11
+ import './Header.css';
12
+ const b = block('header');
13
+ const MobileMenuButton = ({ isSidebarOpened, onSidebarOpenedChange, }) => {
14
+ const iconProps = { icon: isSidebarOpened ? NavigationClose : NavigationOpen, iconSize: 36 };
15
+ return (React.createElement(Control, Object.assign({ className: b('mobile-menu-button'), onClick: (e) => {
16
+ e.stopPropagation();
17
+ onSidebarOpenedChange(!isSidebarOpened);
18
+ }, size: "l" }, iconProps)));
19
+ };
20
+ export const Header = ({ data, logo }) => {
21
+ const { leftItems, rightItems } = data;
22
+ const [isSidebarOpened, setIsSidebarOpened] = useState(false);
23
+ const [activeItemIndex, setActiveItemIndex] = useState(-1);
24
+ const onActiveItemChange = useCallback((index) => {
25
+ setActiveItemIndex(index);
26
+ }, []);
27
+ const onSidebarOpenedChange = useCallback((isOpen) => {
28
+ setIsSidebarOpened(isOpen);
29
+ }, []);
30
+ const hideSidebar = useCallback(() => {
31
+ setIsSidebarOpened(false);
32
+ }, []);
33
+ return (React.createElement(Grid, { className: b() },
34
+ React.createElement(Row, null,
35
+ React.createElement(Col, null,
36
+ React.createElement("header", { className: b('wrapper') },
37
+ logo && (React.createElement("div", { className: b('left') },
38
+ React.createElement(Logo, Object.assign({}, logo, { className: b('logo') })))),
39
+ React.createElement("div", { className: b('navigation-container') },
40
+ React.createElement(Navigation, { className: b('navigation'), links: leftItems, activeItemIndex: activeItemIndex, onActiveItemChange: onActiveItemChange })),
41
+ React.createElement("div", { className: b('right') },
42
+ React.createElement(MobileMenuButton, { isSidebarOpened: isSidebarOpened, onSidebarOpenedChange: onSidebarOpenedChange }),
43
+ rightItems && (React.createElement("div", { className: b('buttons') }, rightItems.map((button) => (React.createElement(NavigationItem, { key: button.text, data: button, className: b('button') })))))),
44
+ React.createElement(OutsideClick, { onOutsideClick: () => onSidebarOpenedChange(false) },
45
+ React.createElement(MobileNavigation, { topItems: leftItems, bottomItems: rightItems, isOpened: isSidebarOpened, activeItemIndex: activeItemIndex, onActiveItemChange: onActiveItemChange, onClose: hideSidebar })))))));
46
+ };
47
+ export default Header;
@@ -0,0 +1,23 @@
1
+ .logo {
2
+ margin: 0;
3
+ }
4
+
5
+ /* use this for style redefinitions to awoid problems with
6
+ unpredictable css rules order in build */
7
+ .logo {
8
+ display: flex;
9
+ align-items: center;
10
+ font-weight: var(--yc-text-accent-font-weight);
11
+ font-size: var(--yc-text-header-1-font-size);
12
+ line-height: var(--yc-text-header-1-line-height);
13
+ color: var(--pc-text-header-color);
14
+ font-weight: var(--yc-text-accent-font-weight);
15
+ }
16
+ .logo__icon {
17
+ display: flex;
18
+ margin-right: 8px;
19
+ object-fit: contain;
20
+ }
21
+ .logo__text {
22
+ white-space: nowrap;
23
+ }
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { NavigationLogo } from '../../../../models';
3
+ import './Logo.css';
4
+ export interface LogoProps extends NavigationLogo {
5
+ className?: string;
6
+ }
7
+ declare const Logo: React.FC<LogoProps>;
8
+ export default Logo;
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import block from 'bem-cn-lite';
3
+ import RouterLink from '../../../RouterLink/RouterLink';
4
+ import { getMediaImage } from '../../../Media/Image/utils';
5
+ import { Image } from '../../../index';
6
+ import './Logo.css';
7
+ const b = block('logo');
8
+ const Logo = ({ icon, text, className }) => {
9
+ const imageData = getMediaImage(icon);
10
+ return (React.createElement(RouterLink, { href: "/", passHref: true },
11
+ React.createElement("div", { className: b(null, className) },
12
+ imageData && React.createElement(Image, Object.assign({ className: b('icon') }, imageData)),
13
+ React.createElement("span", { className: b('text') }, text))));
14
+ };
15
+ export 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: 0 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,14 @@
1
+ import React from 'react';
2
+ import { NavigationItem as NavigationItemModel } from '../../../../models/navigation';
3
+ import './MobileNavigation.css';
4
+ export interface MobileNavigationProps {
5
+ className?: string;
6
+ isOpened?: boolean;
7
+ topItems?: NavigationItemModel[];
8
+ bottomItems?: NavigationItemModel[];
9
+ activeItemIndex: number;
10
+ onClose: () => void;
11
+ onActiveItemChange: (index: number) => void;
12
+ }
13
+ declare const MobileNavigation: React.FC<MobileNavigationProps>;
14
+ export default MobileNavigation;
@@ -0,0 +1,43 @@
1
+ import block from 'bem-cn-lite';
2
+ import React, { useRef, useCallback } from 'react';
3
+ import { Popup, Portal } from '@gravity-ui/uikit';
4
+ import Foldable from '../../../Foldable/Foldable';
5
+ import { NavigationItemType, } from '../../../../models/navigation';
6
+ import NavigationItem from '../NavigationItem/NavigationItem';
7
+ import './MobileNavigation.css';
8
+ const b = block('mobile-navigation');
9
+ const MobileNavigationDropdown = ({ data, onItemClick, onToggle, isOpened = false, }) => {
10
+ const ref = useRef(null);
11
+ return (React.createElement("div", { ref: ref, className: b('dropdown') },
12
+ React.createElement(NavigationItem, { data: data, onClick: onToggle, isOpened: isOpened }),
13
+ isOpened && (React.createElement(Popup, { anchorRef: ref, open: isOpened, className: b('popup') }, data.items.map((item) => (React.createElement(NavigationItem, { key: item.text, data: item, className: b('dropdown-item'), onClick: onItemClick })))))));
14
+ };
15
+ const MobileNavigationItem = ({ link, index, isActive, onActiveItemChange, onClose, }) => {
16
+ const toggleActive = useCallback((e) => {
17
+ e.stopPropagation();
18
+ if (onActiveItemChange) {
19
+ onActiveItemChange(isActive ? -1 : index);
20
+ }
21
+ }, [isActive, index, onActiveItemChange]);
22
+ const onItemClick = useCallback((e) => {
23
+ toggleActive(e);
24
+ onClose();
25
+ }, [toggleActive, onClose]);
26
+ return (React.createElement("li", { key: index, className: b('links-item') }, link.type === NavigationItemType.Dropdown ? (React.createElement(MobileNavigationDropdown, { data: link, onToggle: toggleActive, isOpened: isActive, onItemClick: onItemClick })) : (React.createElement(NavigationItem, { data: link, onClick: onItemClick }))));
27
+ };
28
+ const MobileNavigation = (props) => {
29
+ if (typeof window === 'undefined') {
30
+ return null;
31
+ }
32
+ const { isOpened, topItems, bottomItems, activeItemIndex, onActiveItemChange, onClose } = props;
33
+ return (React.createElement(Portal, null,
34
+ React.createElement(Foldable, { key: topItems === null || topItems === void 0 ? void 0 : topItems.length, className: b(), isOpened: Boolean(isOpened) },
35
+ React.createElement("div", { className: b('wrapper') },
36
+ React.createElement("nav", null,
37
+ React.createElement("ul", { className: b('links') }, topItems === null || topItems === void 0 ? void 0 : topItems.map((link, index) => {
38
+ const isActive = index === activeItemIndex;
39
+ return (React.createElement(MobileNavigationItem, { key: index, link: link, index: index, isActive: isOpened && isActive, onClose: onClose, onActiveItemChange: onActiveItemChange }));
40
+ }))), bottomItems === null || bottomItems === void 0 ? void 0 :
41
+ bottomItems.map((item) => (React.createElement(NavigationItem, { key: item.text, data: item, className: b('button') })))))));
42
+ };
43
+ export 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,19 @@
1
+ import React, { MouseEventHandler } from 'react';
2
+ import { NavigationDropdownItem, NavigationItem as NavigationItemModel } from '../../../../models/navigation';
3
+ import './Navigation.css';
4
+ export interface NavigationProps {
5
+ links: NavigationItemModel[];
6
+ activeItemIndex: number;
7
+ onActiveItemChange: (index: number) => void;
8
+ className?: string;
9
+ highlightActiveItem?: boolean;
10
+ }
11
+ export interface NavigationDropdownProps {
12
+ data: NavigationDropdownItem;
13
+ onClick: MouseEventHandler;
14
+ isActive: boolean;
15
+ position: number;
16
+ hidePopup: () => void;
17
+ }
18
+ declare const Navigation: React.FC<NavigationProps>;
19
+ export default Navigation;
@@ -0,0 +1,70 @@
1
+ import { __rest } from "tslib";
2
+ import _ from 'lodash';
3
+ import block from 'bem-cn-lite';
4
+ import React, { Fragment, useState, useEffect, useCallback, useContext, useRef, } from 'react';
5
+ import OverflowScroller from '../../../OverflowScroller/OverflowScroller';
6
+ import { NavigationItemType, } from '../../../../models/navigation';
7
+ import NavigationPopup from '../NavigationPopup/NavigationPopup';
8
+ import NavigationItem from '../NavigationItem/NavigationItem';
9
+ import { LocationContext } from '../../../../context/locationContext';
10
+ import { BreakpointContext } from '../../../../context/breakpointContext';
11
+ import './Navigation.css';
12
+ const b = block('navigation');
13
+ const NavigationDropdown = ({ data, isActive, position, hidePopup, onClick, }) => {
14
+ const { text, items } = data, popupProps = __rest(data, ["text", "items"]);
15
+ return (React.createElement(Fragment, null,
16
+ React.createElement(NavigationItem, { className: b('link'), onClick: onClick, isOpened: isActive, data: { text, type: NavigationItemType.Dropdown } }),
17
+ isActive && (React.createElement(NavigationPopup, Object.assign({ left: position, onClose: hidePopup, items: items }, popupProps)))));
18
+ };
19
+ const Navigation = ({ className, onActiveItemChange, links, activeItemIndex, highlightActiveItem, }) => {
20
+ const { asPath, pathname } = useContext(LocationContext);
21
+ const breakpoint = useContext(BreakpointContext);
22
+ const itemRefs = useRef([]);
23
+ const [itemPositions, setItemPosition] = useState([]);
24
+ const [lastLeftScroll, setLastLeftScroll] = useState(0);
25
+ const hidePopup = useCallback(() => {
26
+ onActiveItemChange(-1);
27
+ }, [onActiveItemChange]);
28
+ const getItemClickHandler = useCallback((index) => (e) => {
29
+ e.stopPropagation();
30
+ onActiveItemChange(index === activeItemIndex ? -1 : index);
31
+ }, [activeItemIndex, onActiveItemChange]);
32
+ const calculateItemPositions = useCallback(() => {
33
+ if (itemRefs.current.length) {
34
+ const currentItemPositions = itemRefs.current.map((itemRef) => (itemRef && itemRef.getBoundingClientRect().left) || 0);
35
+ setItemPosition(currentItemPositions);
36
+ }
37
+ }, []);
38
+ useEffect(() => {
39
+ const debouncedCalculateItemPositions = _.debounce(calculateItemPositions, 100);
40
+ const calculateOnScroll = _.debounce(() => {
41
+ const curLeftScroll = window.pageXOffset;
42
+ if (curLeftScroll !== lastLeftScroll) {
43
+ setLastLeftScroll(window.pageXOffset);
44
+ calculateItemPositions();
45
+ }
46
+ }, 100);
47
+ calculateItemPositions();
48
+ setLastLeftScroll(window.pageXOffset);
49
+ window.addEventListener('resize', debouncedCalculateItemPositions);
50
+ window.addEventListener('scroll', calculateOnScroll);
51
+ return () => {
52
+ window.removeEventListener(`resize`, calculateItemPositions);
53
+ window.removeEventListener('scroll', calculateOnScroll);
54
+ };
55
+ }, [calculateItemPositions, itemRefs, lastLeftScroll]);
56
+ useEffect(() => {
57
+ hidePopup();
58
+ }, [hidePopup, asPath, pathname, breakpoint]);
59
+ return (React.createElement(OverflowScroller, { className: b(null, className), onScrollStart: hidePopup, onScrollEnd: calculateItemPositions },
60
+ React.createElement("nav", null,
61
+ React.createElement("ul", { className: b('links') }, links.map((link, index) => {
62
+ const isActive = index === activeItemIndex;
63
+ const onClick = getItemClickHandler(index);
64
+ return (React.createElement("li", { ref: (el) => itemRefs.current.push(el), key: index, className: b('links-item') },
65
+ link.type === NavigationItemType.Dropdown ? (React.createElement(NavigationDropdown, { data: link, onClick: onClick, isActive: isActive, position: itemPositions[index], hidePopup: hidePopup })) : (React.createElement(NavigationItem, { data: link, onClick: onClick })),
66
+ highlightActiveItem && isActive && (React.createElement("div", { className: b('slider-container') },
67
+ React.createElement("div", { className: b('slider') })))));
68
+ })))));
69
+ };
70
+ export default Navigation;
@@ -0,0 +1,41 @@
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
+ display: flex;
32
+ width: 20px;
33
+ height: 20px;
34
+ margin-right: 8px;
35
+ border-radius: 50%;
36
+ object-fit: cover;
37
+ }
38
+ .navigation-item__dropdown {
39
+ margin-left: 7px;
40
+ color: var(--yc-color-text-secondary);
41
+ }
@@ -0,0 +1,13 @@
1
+ import React, { MouseEventHandler } from 'react';
2
+ import { NavigationButtonItem, NavigationDropdownItem, NavigationSocialItem, NavigationLinkItem } from '../../../../models';
3
+ import './NavigationItem.css';
4
+ declare type DropdownItemData = Omit<NavigationDropdownItem, 'items'>;
5
+ export declare type NavigationItemData = NavigationLinkItem | NavigationButtonItem | NavigationSocialItem | DropdownItemData;
6
+ export interface NavigationItemProps {
7
+ data: NavigationItemData;
8
+ className?: string;
9
+ onClick?: MouseEventHandler;
10
+ isOpened?: boolean;
11
+ }
12
+ declare const NavigationItem: React.FC<NavigationItemProps>;
13
+ export default NavigationItem;
@@ -0,0 +1,59 @@
1
+ import { __rest } from "tslib";
2
+ import React, { Fragment, useContext, useMemo } from 'react';
3
+ import block from 'bem-cn-lite';
4
+ import { RouterLink, ToggleArrow, Button, Image } from '../../../index';
5
+ import { getLinkProps } from '../../../../utils';
6
+ import { LocationContext } from '../../../../context/locationContext';
7
+ import { NavigationItemType, } from '../../../../models';
8
+ import { NavigationArrow } from '../../../../icons';
9
+ import SocialIcon from '../SocialIcon/SocialIcon';
10
+ import { getMediaImage } from '../../../Media/Image/utils';
11
+ import './NavigationItem.css';
12
+ const b = block('navigation-item');
13
+ const Content = ({ text, icon }) => (React.createElement(Fragment, null,
14
+ icon && React.createElement(Image, Object.assign({ className: b('icon') }, icon)),
15
+ React.createElement("span", { className: b('text') }, text)));
16
+ const NavigationDropdown = (_a) => {
17
+ var { text, icon, isOpened } = _a, props = __rest(_a, ["text", "icon", "isOpened"]);
18
+ const iconData = icon && getMediaImage(icon);
19
+ return (React.createElement("span", Object.assign({}, props),
20
+ React.createElement(Content, { text: text, icon: iconData }),
21
+ React.createElement(ToggleArrow, { className: b('dropdown'), size: 12, type: 'vertical', iconType: "navigation", open: isOpened })));
22
+ };
23
+ const NavigationLink = (props) => {
24
+ const { hostname, Link } = useContext(LocationContext);
25
+ const { url, text, icon, arrow, target } = props, rest = __rest(props, ["url", "text", "icon", "arrow", "target"]);
26
+ const linkExtraProps = getLinkProps(url, hostname, target);
27
+ const iconData = icon && getMediaImage(icon);
28
+ const content = (React.createElement(Fragment, null,
29
+ React.createElement(Content, { text: text, icon: iconData }),
30
+ arrow && React.createElement(NavigationArrow, { className: b('arrow') })));
31
+ if ((linkExtraProps === null || linkExtraProps === void 0 ? void 0 : linkExtraProps.target) || !Link) {
32
+ return (React.createElement("a", Object.assign({ href: url, title: text }, rest, linkExtraProps), content));
33
+ }
34
+ else {
35
+ return (React.createElement(RouterLink, { href: url, passHref: true },
36
+ React.createElement("a", Object.assign({}, rest), content)));
37
+ }
38
+ };
39
+ const NavigationButton = (props) => {
40
+ const { url, target } = props;
41
+ return target ? (React.createElement(Button, Object.assign({}, props, { url: url }))) : (React.createElement(RouterLink, { href: url },
42
+ React.createElement(Button, Object.assign({}, props, { url: url }))));
43
+ };
44
+ //todo: add types support form component in map
45
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
46
+ const NavigationItemsMap = {
47
+ [NavigationItemType.Button]: NavigationButton,
48
+ [NavigationItemType.Social]: SocialIcon,
49
+ [NavigationItemType.Dropdown]: NavigationDropdown,
50
+ [NavigationItemType.Link]: NavigationLink,
51
+ };
52
+ const NavigationItem = (_a) => {
53
+ var { data, className } = _a, props = __rest(_a, ["data", "className"]);
54
+ const { type = NavigationItemType.Link } = data;
55
+ const Component = NavigationItemsMap[type];
56
+ const componentProps = useMemo(() => (Object.assign(Object.assign({ className: b({ type }, className) }, data), props)), [className, data, props, type]);
57
+ return React.createElement(Component, Object.assign({}, componentProps));
58
+ };
59
+ export default NavigationItem;
@@ -0,0 +1,33 @@
1
+ /* use this for style redefinitions to awoid problems with
2
+ unpredictable css rules order in build */
3
+ .navigation-popup {
4
+ position: fixed;
5
+ top: calc(var(--header-height) - 16px);
6
+ padding-right: 4px;
7
+ padding-left: 4px;
8
+ transform: translateX(calc(calc(8px * 2) * -1));
9
+ z-index: 101;
10
+ display: flex;
11
+ flex-direction: column;
12
+ min-width: 220px;
13
+ padding: 16px;
14
+ border: 1px solid var(--yc-color-line-generic);
15
+ border-top-width: 0;
16
+ border-radius: calc(var(--pc-border-radius) / 2);
17
+ background: var(--yc-color-base-float);
18
+ box-shadow: 0 3px 10px var(--yc-color-sfx-shadow);
19
+ }
20
+ @media (max-width: 768px) {
21
+ .navigation-popup {
22
+ display: none;
23
+ }
24
+ }
25
+ .navigation-popup__link {
26
+ height: 36px;
27
+ padding: 8px 12px;
28
+ border-radius: 8px;
29
+ }
30
+ .navigation-popup__link:hover {
31
+ color: var(--yc-color-text-primary);
32
+ background-color: var(--yc-color-base-simple-hover);
33
+ }
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import { NavigationLinkItem } from '../../../../models';
3
+ import './NavigationPopup.css';
4
+ export interface NavigationPopupProps {
5
+ items: NavigationLinkItem[];
6
+ onClose: () => void;
7
+ left?: number;
8
+ className?: string;
9
+ }
10
+ export declare const NavigationPopup: React.FC<NavigationPopupProps>;
11
+ export default NavigationPopup;