@gravity-ui/page-constructor 3.10.3 → 3.12.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.
Files changed (139) hide show
  1. package/README.md +9 -11
  2. package/build/cjs/components/Media/Image/Image.js +3 -2
  3. package/build/cjs/editor/components/ControlPanel/ControlPanel.js +4 -1
  4. package/build/cjs/editor/components/DeviceEmulation/DeviceEmulation.d.ts +7 -0
  5. package/build/cjs/editor/components/DeviceEmulation/DeviceEmulation.js +10 -0
  6. package/build/cjs/editor/components/DeviceEmulation/DeviceEmulationMobile/DeviceEmulationMobile.css +33 -0
  7. package/build/cjs/editor/components/DeviceEmulation/DeviceEmulationMobile/DeviceEmulationMobile.d.ts +8 -0
  8. package/build/cjs/editor/components/DeviceEmulation/DeviceEmulationMobile/DeviceEmulationMobile.js +41 -0
  9. package/build/cjs/editor/components/DeviceEmulation/utils.d.ts +4 -0
  10. package/build/cjs/editor/components/DeviceEmulation/utils.js +7 -0
  11. package/build/cjs/editor/components/Layout/Layout.js +3 -1
  12. package/build/cjs/editor/containers/Editor/Editor.d.ts +1 -1
  13. package/build/cjs/editor/containers/Editor/Editor.js +34 -9
  14. package/build/cjs/editor/containers/Form/Form.js +2 -2
  15. package/build/cjs/editor/context.d.ts +9 -0
  16. package/build/cjs/editor/context.js +6 -0
  17. package/build/cjs/editor/icons/Tablet.d.ts +2 -0
  18. package/build/cjs/editor/icons/Tablet.js +9 -0
  19. package/build/cjs/editor/types/index.d.ts +14 -5
  20. package/build/cjs/editor/types/index.js +3 -1
  21. package/build/cjs/editor/utils/index.d.ts +2 -0
  22. package/build/cjs/editor/utils/index.js +4 -1
  23. package/build/cjs/editor/widget/constants.d.ts +4 -0
  24. package/build/cjs/editor/widget/constants.js +8 -0
  25. package/build/cjs/editor/widget/index.d.ts +21 -0
  26. package/build/cjs/editor/widget/index.js +76 -0
  27. package/build/cjs/editor/widget/utils.d.ts +1 -0
  28. package/build/cjs/editor/widget/utils.js +19 -0
  29. package/build/cjs/hooks/useHeightCalculator.js +1 -1
  30. package/build/cjs/models/navigation.d.ts +3 -2
  31. package/build/{esm/navigation/components/Header/Header.css → cjs/navigation/components/DesktopNavigation/DesktopNavigation.css} +28 -36
  32. package/build/cjs/navigation/components/DesktopNavigation/DesktopNavigation.d.ts +4 -0
  33. package/build/cjs/navigation/components/DesktopNavigation/DesktopNavigation.js +21 -0
  34. package/build/cjs/navigation/components/MobileMenuButton/MobileMenuButton.css +7 -0
  35. package/build/cjs/navigation/components/MobileMenuButton/MobileMenuButton.d.ts +3 -0
  36. package/build/cjs/navigation/components/MobileMenuButton/MobileMenuButton.js +15 -0
  37. package/build/cjs/navigation/components/MobileNavigation/MobileNavigation.css +10 -5
  38. package/build/cjs/navigation/components/MobileNavigation/MobileNavigation.d.ts +1 -10
  39. package/build/cjs/navigation/components/MobileNavigation/MobileNavigation.js +7 -30
  40. package/build/cjs/navigation/components/Navigation/Navigation.css +8 -13
  41. package/build/cjs/navigation/components/Navigation/Navigation.d.ts +4 -7
  42. package/build/cjs/navigation/components/Navigation/Navigation.js +37 -15
  43. package/build/cjs/navigation/components/NavigationItem/NavigationItem.css +28 -0
  44. package/build/cjs/navigation/components/NavigationItem/NavigationItem.d.ts +3 -9
  45. package/build/cjs/navigation/components/NavigationItem/NavigationItem.js +15 -6
  46. package/build/cjs/navigation/components/NavigationItem/components/GithubButton/GithubButton.d.ts +1 -1
  47. package/build/cjs/navigation/components/NavigationItem/components/NavigationButton/NavigationButton.d.ts +1 -1
  48. package/build/cjs/navigation/components/NavigationItem/components/NavigationDropdown/NavigationDropdown.d.ts +5 -4
  49. package/build/cjs/navigation/components/NavigationItem/components/NavigationDropdown/NavigationDropdown.js +12 -7
  50. package/build/cjs/navigation/components/NavigationItem/components/NavigationLink/NavigationLink.d.ts +1 -1
  51. package/build/cjs/navigation/components/NavigationList/NavigationList.d.ts +3 -0
  52. package/build/cjs/navigation/components/NavigationList/NavigationList.js +11 -0
  53. package/build/cjs/navigation/components/NavigationListItem/NavigationListItem.d.ts +4 -13
  54. package/build/cjs/navigation/components/NavigationListItem/NavigationListItem.js +6 -13
  55. package/build/cjs/navigation/components/NavigationPopup/NavigationPopup.css +5 -4
  56. package/build/cjs/navigation/components/NavigationPopup/NavigationPopup.d.ts +1 -8
  57. package/build/cjs/navigation/components/NavigationPopup/NavigationPopup.js +6 -6
  58. package/build/cjs/navigation/containers/Layout/Layout.js +2 -2
  59. package/build/cjs/navigation/models.d.ts +63 -0
  60. package/build/cjs/navigation/{constants.js → models.js} +7 -1
  61. package/build/cjs/navigation/utils.d.ts +11 -1
  62. package/build/cjs/navigation/utils.js +19 -1
  63. package/build/esm/components/Media/Image/Image.js +3 -2
  64. package/build/esm/editor/components/ControlPanel/ControlPanel.js +6 -3
  65. package/build/esm/editor/components/DeviceEmulation/DeviceEmulation.d.ts +7 -0
  66. package/build/esm/editor/components/DeviceEmulation/DeviceEmulation.js +7 -0
  67. package/build/esm/editor/components/DeviceEmulation/DeviceEmulationMobile/DeviceEmulationMobile.css +33 -0
  68. package/build/esm/editor/components/DeviceEmulation/DeviceEmulationMobile/DeviceEmulationMobile.d.ts +9 -0
  69. package/build/esm/editor/components/DeviceEmulation/DeviceEmulationMobile/DeviceEmulationMobile.js +40 -0
  70. package/build/esm/editor/components/DeviceEmulation/utils.d.ts +4 -0
  71. package/build/esm/editor/components/DeviceEmulation/utils.js +3 -0
  72. package/build/esm/editor/components/Layout/Layout.js +3 -1
  73. package/build/esm/editor/containers/Editor/Editor.d.ts +1 -1
  74. package/build/esm/editor/containers/Editor/Editor.js +35 -10
  75. package/build/esm/editor/containers/Form/Form.js +2 -2
  76. package/build/esm/editor/context.d.ts +9 -0
  77. package/build/esm/editor/context.js +2 -0
  78. package/build/esm/editor/icons/Tablet.d.ts +2 -0
  79. package/build/esm/editor/icons/Tablet.js +4 -0
  80. package/build/esm/editor/types/index.d.ts +14 -5
  81. package/build/esm/editor/types/index.js +3 -1
  82. package/build/esm/editor/utils/index.d.ts +2 -0
  83. package/build/esm/editor/utils/index.js +2 -0
  84. package/build/esm/editor/widget/constants.d.ts +4 -0
  85. package/build/esm/editor/widget/constants.js +5 -0
  86. package/build/esm/editor/widget/index.d.ts +21 -0
  87. package/build/esm/editor/widget/index.js +71 -0
  88. package/build/esm/editor/widget/utils.d.ts +1 -0
  89. package/build/esm/editor/widget/utils.js +15 -0
  90. package/build/esm/hooks/useHeightCalculator.js +1 -1
  91. package/build/esm/models/navigation.d.ts +3 -2
  92. package/build/{cjs/navigation/components/Header/Header.css → esm/navigation/components/DesktopNavigation/DesktopNavigation.css} +28 -36
  93. package/build/esm/navigation/components/DesktopNavigation/DesktopNavigation.d.ts +5 -0
  94. package/build/esm/navigation/components/DesktopNavigation/DesktopNavigation.js +19 -0
  95. package/build/esm/navigation/components/MobileMenuButton/MobileMenuButton.css +7 -0
  96. package/build/esm/navigation/components/MobileMenuButton/MobileMenuButton.d.ts +4 -0
  97. package/build/esm/navigation/components/MobileMenuButton/MobileMenuButton.js +11 -0
  98. package/build/esm/navigation/components/MobileNavigation/MobileNavigation.css +10 -5
  99. package/build/esm/navigation/components/MobileNavigation/MobileNavigation.d.ts +1 -10
  100. package/build/esm/navigation/components/MobileNavigation/MobileNavigation.js +9 -31
  101. package/build/esm/navigation/components/Navigation/Navigation.css +8 -13
  102. package/build/esm/navigation/components/Navigation/Navigation.d.ts +4 -7
  103. package/build/esm/navigation/components/Navigation/Navigation.js +35 -15
  104. package/build/esm/navigation/components/NavigationItem/NavigationItem.css +28 -0
  105. package/build/esm/navigation/components/NavigationItem/NavigationItem.d.ts +4 -9
  106. package/build/esm/navigation/components/NavigationItem/NavigationItem.js +16 -6
  107. package/build/esm/navigation/components/NavigationItem/components/GithubButton/GithubButton.d.ts +1 -1
  108. package/build/esm/navigation/components/NavigationItem/components/NavigationButton/NavigationButton.d.ts +1 -1
  109. package/build/esm/navigation/components/NavigationItem/components/NavigationDropdown/NavigationDropdown.d.ts +5 -4
  110. package/build/esm/navigation/components/NavigationItem/components/NavigationDropdown/NavigationDropdown.js +12 -7
  111. package/build/esm/navigation/components/NavigationItem/components/NavigationLink/NavigationLink.d.ts +1 -1
  112. package/build/esm/navigation/components/NavigationList/NavigationList.d.ts +3 -0
  113. package/build/esm/navigation/components/NavigationList/NavigationList.js +7 -0
  114. package/build/esm/navigation/components/NavigationListItem/NavigationListItem.d.ts +4 -14
  115. package/build/esm/navigation/components/NavigationListItem/NavigationListItem.js +5 -10
  116. package/build/esm/navigation/components/NavigationPopup/NavigationPopup.css +5 -4
  117. package/build/esm/navigation/components/NavigationPopup/NavigationPopup.d.ts +1 -8
  118. package/build/esm/navigation/components/NavigationPopup/NavigationPopup.js +6 -6
  119. package/build/esm/navigation/containers/Layout/Layout.js +2 -2
  120. package/build/esm/navigation/models.d.ts +63 -0
  121. package/build/esm/navigation/{constants.js → models.js} +6 -0
  122. package/build/esm/navigation/utils.d.ts +11 -1
  123. package/build/esm/navigation/utils.js +17 -0
  124. package/package.json +39 -16
  125. package/server/models/navigation.d.ts +3 -2
  126. package/widget/index.js +1 -0
  127. package/CHANGELOG.md +0 -1469
  128. package/build/cjs/navigation/components/Header/Header.d.ts +0 -8
  129. package/build/cjs/navigation/components/Header/Header.js +0 -86
  130. package/build/cjs/navigation/components/NavigationDropdownItem/NavigationDropdownItem.d.ts +0 -11
  131. package/build/cjs/navigation/components/NavigationDropdownItem/NavigationDropdownItem.js +0 -15
  132. package/build/cjs/navigation/components/NavigationListItem/NavigationListItem.css +0 -27
  133. package/build/cjs/navigation/constants.d.ts +0 -6
  134. package/build/esm/navigation/components/Header/Header.d.ts +0 -9
  135. package/build/esm/navigation/components/Header/Header.js +0 -82
  136. package/build/esm/navigation/components/NavigationDropdownItem/NavigationDropdownItem.d.ts +0 -11
  137. package/build/esm/navigation/components/NavigationDropdownItem/NavigationDropdownItem.js +0 -13
  138. package/build/esm/navigation/components/NavigationListItem/NavigationListItem.css +0 -27
  139. package/build/esm/navigation/constants.d.ts +0 -6
@@ -0,0 +1,71 @@
1
+ //widget bundle available after build only
2
+ //@ts-ignore
3
+ import bundle from '../../../../widget';
4
+ import { DeviceFrameMessageType } from './constants';
5
+ import { getHostStyles } from './utils';
6
+ export class DeviceIframe {
7
+ constructor(parentElement, { className = '', initialData, settings }) {
8
+ const iframe = document.createElement('iframe');
9
+ parentElement.appendChild(iframe);
10
+ if (iframe.contentWindow) {
11
+ const frameDoc = iframe.contentWindow.document;
12
+ iframe.className = className;
13
+ frameDoc.body.classList.add(...document.body.classList, ...className.split(' '));
14
+ iframe.style.visibility = 'hidden';
15
+ this.iframeElement = iframe;
16
+ this.initialData = initialData;
17
+ this.settings = settings;
18
+ window.addEventListener('message', this.onInit.bind(this));
19
+ this.addWidgetScript();
20
+ this.addCustomStyles();
21
+ }
22
+ }
23
+ onDataUpdate(data) {
24
+ var _a, _b;
25
+ (_b = (_a = this.iframeElement) === null || _a === void 0 ? void 0 : _a.contentWindow) === null || _b === void 0 ? void 0 : _b.postMessage({
26
+ type: DeviceFrameMessageType.Update,
27
+ data,
28
+ }, window.origin);
29
+ }
30
+ onActivenessUpdate(active) {
31
+ if (this.iframeElement) {
32
+ this.iframeElement.style.visibility = active ? 'visible' : 'hidden';
33
+ }
34
+ }
35
+ destroy() {
36
+ window.removeEventListener('message', this.onInit.bind(this));
37
+ }
38
+ addWidgetScript() {
39
+ var _a, _b;
40
+ const frameDoc = (_b = (_a = this.iframeElement) === null || _a === void 0 ? void 0 : _a.contentWindow) === null || _b === void 0 ? void 0 : _b.document;
41
+ if (frameDoc) {
42
+ const head = frameDoc === null || frameDoc === void 0 ? void 0 : frameDoc.getElementsByTagName('head')[0];
43
+ const script = frameDoc.createElement('script');
44
+ script.appendChild(document.createTextNode(bundle));
45
+ head.appendChild(script);
46
+ }
47
+ }
48
+ addCustomStyles() {
49
+ var _a, _b;
50
+ const { applyHostStyles, customStyles } = this.settings || {};
51
+ const frameDoc = (_b = (_a = this.iframeElement) === null || _a === void 0 ? void 0 : _a.contentWindow) === null || _b === void 0 ? void 0 : _b.document;
52
+ if (frameDoc) {
53
+ const head = frameDoc === null || frameDoc === void 0 ? void 0 : frameDoc.getElementsByTagName('head')[0];
54
+ let styles = applyHostStyles ? getHostStyles() : '';
55
+ if (customStyles) {
56
+ styles += `\n${customStyles}`;
57
+ }
58
+ if (styles) {
59
+ const style = frameDoc.createElement('style');
60
+ style.appendChild(document.createTextNode(styles));
61
+ head.appendChild(style);
62
+ }
63
+ }
64
+ }
65
+ onInit(event) {
66
+ const { type } = event.data;
67
+ if (type === DeviceFrameMessageType.Ready && this.initialData) {
68
+ this.onDataUpdate(this.initialData);
69
+ }
70
+ }
71
+ }
@@ -0,0 +1 @@
1
+ export declare const getHostStyles: () => string;
@@ -0,0 +1,15 @@
1
+ export const getHostStyles = () => {
2
+ return [...document.styleSheets]
3
+ .map((styleSheet) => {
4
+ try {
5
+ return [...styleSheet.cssRules].map((rule) => rule.cssText).join('');
6
+ }
7
+ catch (e) {
8
+ //eslint-disable-next-line no-console
9
+ console.log(`Access to stylesheet ${styleSheet.href} is denied. Ignoring...`);
10
+ return '';
11
+ }
12
+ })
13
+ .filter(Boolean)
14
+ .join('\n');
15
+ };
@@ -13,7 +13,7 @@ const useHeightCalculator = (containerRef, options = DEFAULT_OPTIONS) => {
13
13
  }, [containerRef, containerHeight, setContainerHeight]);
14
14
  useEffect(() => {
15
15
  const handleResize = _.debounce(calculateContainerHeight, recalculateOnResizeDelay);
16
- calculateContainerHeight();
16
+ handleResize();
17
17
  window.addEventListener('resize', handleResize, { passive: true });
18
18
  return () => {
19
19
  window.removeEventListener('resize', handleResize);
@@ -44,6 +44,8 @@ export interface NavigationButtonItem extends ButtonProps {
44
44
  export interface NavigationDropdownItem extends NavigationItemBase {
45
45
  type: NavigationItemType.Dropdown;
46
46
  items: NavigationLinkItem[];
47
+ hidePopup: () => void;
48
+ isActive: boolean;
47
49
  }
48
50
  export interface NavigationSocialItem extends Omit<NavigationItemBase, 'text'> {
49
51
  type: NavigationItemType.Social;
@@ -51,8 +53,7 @@ export interface NavigationSocialItem extends Omit<NavigationItemBase, 'text'> {
51
53
  url: string;
52
54
  }
53
55
  export type NavigationItemModel = NavigationLinkItem | NavigationButtonItem | NavigationDropdownItem;
54
- export type NavigationItemData = NavigationLinkItem | NavigationButtonItem | NavigationSocialItem | DropdownItemData;
55
- export type DropdownItemData = Omit<NavigationDropdownItem, 'items'>;
56
+ export type NavigationItemData = NavigationLinkItem | NavigationButtonItem | NavigationSocialItem | NavigationDropdownItem;
56
57
  export interface NavigationLogoData {
57
58
  icon: ImageProps;
58
59
  text?: string;
@@ -1,52 +1,39 @@
1
1
  /* use this for style redefinitions to awoid problems with
2
2
  unpredictable css rules order in build */
3
- .pc-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
- }
13
- .pc-header_with-border {
14
- box-shadow: inset 0 -1px 0 var(--yc-color-line-generic);
15
- }
16
- .pc-header__wrapper {
3
+ .pc-desktop-navigation__wrapper {
17
4
  display: flex;
18
5
  justify-content: space-between;
19
6
  align-items: center;
20
7
  height: var(--header-height);
21
8
  }
22
9
  @media (min-width: 769px) {
23
- .pc-header__mobile-menu-button.pc-header__mobile-menu-button {
10
+ .pc-desktop-navigation__mobile-menu-button.pc-desktop-navigation__mobile-menu-button {
24
11
  display: none;
25
12
  }
26
13
  }
27
14
 
28
- .pc-header__navigation, .pc-header__left, .pc-header__right {
15
+ .pc-desktop-navigation__navigation, .pc-desktop-navigation__left, .pc-desktop-navigation__right {
29
16
  display: flex;
30
17
  align-items: center;
31
18
  }
32
- .pc-header__navigation.pc-header__navigation {
19
+ .pc-desktop-navigation__navigation.pc-desktop-navigation__navigation {
33
20
  position: relative;
34
21
  flex: 1 0 0;
35
22
  justify-content: flex-start;
36
23
  }
37
24
  @media (max-width: 768px) {
38
- .pc-header__navigation.pc-header__navigation {
25
+ .pc-desktop-navigation__navigation.pc-desktop-navigation__navigation {
39
26
  display: none;
40
27
  }
41
28
  }
42
29
 
43
- .pc-header__right {
30
+ .pc-desktop-navigation__right {
44
31
  flex: 0;
45
32
  justify-content: flex-end;
46
33
  font-size: var(--yc-text-body-2-font-size);
47
34
  line-height: var(--yc-text-body-2-line-height);
48
35
  }
49
- .pc-header__navigation-container {
36
+ .pc-desktop-navigation__navigation-container {
50
37
  display: flex;
51
38
  overflow-x: hidden;
52
39
  flex: 1 0 0;
@@ -54,7 +41,14 @@ unpredictable css rules order in build */
54
41
  align-items: center;
55
42
  margin-right: 32px;
56
43
  }
57
- .pc-header__buttons {
44
+ .pc-desktop-navigation__button {
45
+ margin-top: 0;
46
+ }
47
+ .pc-desktop-navigation__logo {
48
+ margin: 0 32px 0 0;
49
+ cursor: pointer;
50
+ }
51
+ .pc-desktop-navigation__buttons, .pc-desktop-navigation__links {
58
52
  display: flex;
59
53
  align-items: center;
60
54
  margin: 0;
@@ -62,39 +56,37 @@ unpredictable css rules order in build */
62
56
  list-style: none;
63
57
  }
64
58
  @media (max-width: 768px) {
65
- .pc-header__buttons {
59
+ .pc-desktop-navigation__buttons {
66
60
  display: none;
67
61
  }
68
62
  }
69
- .pc-header__buttons > *:not(:last-child) {
63
+ .pc-desktop-navigation__buttons > *:not(:last-child) {
70
64
  margin-right: 16px;
71
65
  }
72
- .pc-header__buttons-item {
66
+ .pc-desktop-navigation__links {
73
67
  position: relative;
68
+ font-size: var(--yc-text-body-2-font-size);
69
+ line-height: var(--yc-text-body-2-line-height);
74
70
  }
75
- .pc-header__buttons-item:not(:last-child) {
76
- margin-right: 20px;
77
- }
78
- .pc-header__button {
79
- margin-top: 0;
71
+ .pc-desktop-navigation__item {
72
+ position: relative;
80
73
  }
81
- .pc-header__logo {
82
- margin: 0 32px 0 0;
83
- cursor: pointer;
74
+ .pc-desktop-navigation__item:not(:last-child) {
75
+ margin-right: 20px;
84
76
  }
85
77
  @media (max-width: 768px) {
86
- .pc-header__navigation-container {
78
+ .pc-desktop-navigation__navigation-container {
87
79
  justify-content: flex-end;
88
80
  }
89
- .pc-header__left {
81
+ .pc-desktop-navigation__left {
90
82
  flex: 1 0 0;
91
83
  }
92
84
  }
93
85
  @media (max-width: 576px) {
94
- .pc-header__navigation-container {
86
+ .pc-desktop-navigation__navigation-container {
95
87
  margin-right: 12px;
96
88
  }
97
- .pc-header__logo {
89
+ .pc-desktop-navigation__logo {
98
90
  margin-right: 0;
99
91
  }
100
92
  }
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import { DesktopNavigationProps } from '../../models';
3
+ import './DesktopNavigation.css';
4
+ declare const DesktopNavigation: React.FC<DesktopNavigationProps>;
5
+ export default DesktopNavigation;
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import OverflowScroller from '../../../components/OverflowScroller/OverflowScroller';
3
+ import { block } from '../../../utils';
4
+ import { ItemColumnName, NavigationLayout } from '../../models';
5
+ import Logo from '../Logo/Logo';
6
+ import { MobileMenuButton } from '../MobileMenuButton/MobileMenuButton';
7
+ import { NavigationList } from '../NavigationList/NavigationList';
8
+ import './DesktopNavigation.css';
9
+ const b = block('desktop-navigation');
10
+ const DesktopNavigation = ({ logo, leftItemsWithIconSize, rightItemsWithIconSize, isSidebarOpened, onSidebarOpenedChange, onActiveItemChange, activeItemId, }) => (React.createElement("div", { className: b('wrapper') },
11
+ logo && (React.createElement("div", { className: b('left') },
12
+ React.createElement(Logo, Object.assign({}, logo, { className: b('logo') })))),
13
+ React.createElement("div", { className: b('navigation-container') },
14
+ React.createElement(OverflowScroller, { className: b('navigation'), onScrollStart: onActiveItemChange },
15
+ React.createElement(NavigationList, { items: leftItemsWithIconSize, onActiveItemChange: onActiveItemChange, className: b('links'), itemClassName: b('item'), column: ItemColumnName.Left, activeItemId: activeItemId, menuLayout: NavigationLayout.Desktop }))),
16
+ React.createElement("div", { className: b('right') },
17
+ React.createElement(MobileMenuButton, { isSidebarOpened: isSidebarOpened, onSidebarOpenedChange: onSidebarOpenedChange }),
18
+ rightItemsWithIconSize && (React.createElement(NavigationList, { onActiveItemChange: onActiveItemChange, column: ItemColumnName.Right, items: rightItemsWithIconSize, activeItemId: activeItemId, className: b('buttons'), itemClassName: b('item'), menuLayout: NavigationLayout.Desktop })))));
19
+ export default DesktopNavigation;
@@ -0,0 +1,7 @@
1
+ /* use this for style redefinitions to awoid problems with
2
+ unpredictable css rules order in build */
3
+ @media (min-width: 769px) {
4
+ .pc-mobile-menu-button.pc-mobile-menu-button {
5
+ display: none;
6
+ }
7
+ }
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { MobileMenuButtonProps } from '../../models';
3
+ import './MobileMenuButton.css';
4
+ export declare const MobileMenuButton: React.FC<MobileMenuButtonProps>;
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import { Control } from '../../../components';
3
+ import { NavigationClose, NavigationOpen } from '../../../icons';
4
+ import { block } from '../../../utils';
5
+ import './MobileMenuButton.css';
6
+ const b = block('mobile-menu-button');
7
+ const ICON_SIZE = 36;
8
+ export const MobileMenuButton = ({ isSidebarOpened, onSidebarOpenedChange, }) => (React.createElement(Control, { className: b(), onClick: (e) => {
9
+ e.stopPropagation();
10
+ onSidebarOpenedChange(!isSidebarOpened);
11
+ }, size: "l", icon: isSidebarOpened ? NavigationClose : NavigationOpen, iconSize: ICON_SIZE }));
@@ -10,9 +10,16 @@ unpredictable css rules order in build */
10
10
  border-bottom-left-radius: var(--pc-border-radius);
11
11
  background-color: var(--yc-color-base-background);
12
12
  box-shadow: 0 3px 10px var(--yc-color-sfx-shadow);
13
+ max-height: calc(100vh - 2 * var(--header-height));
14
+ overflow-y: scroll;
15
+ scrollbar-width: none;
16
+ -ms-overflow-style: none;
13
17
  font-size: var(--yc-text-body-2-font-size);
14
18
  line-height: var(--yc-text-body-2-line-height);
15
19
  }
20
+ .pc-mobile-navigation::-webkit-scrollbar {
21
+ display: none;
22
+ }
16
23
  @media (min-width: 769px) {
17
24
  .pc-mobile-navigation {
18
25
  display: none;
@@ -24,9 +31,6 @@ unpredictable css rules order in build */
24
31
  .pc-mobile-navigation__button {
25
32
  margin-top: 24px;
26
33
  }
27
- .pc-mobile-navigation__nav {
28
- margin-bottom: 24px;
29
- }
30
34
  .pc-mobile-navigation__rows {
31
35
  position: relative;
32
36
  display: flex;
@@ -35,10 +39,11 @@ unpredictable css rules order in build */
35
39
  margin: 0;
36
40
  padding: 0;
37
41
  list-style: none;
38
- }
39
- .pc-mobile-navigation__rows-item:not(:last-child) {
40
42
  margin-bottom: 24px;
41
43
  }
44
+ .pc-mobile-navigation__rows:last-child {
45
+ margin-bottom: 0;
46
+ }
42
47
  .pc-mobile-navigation__dropdown-item:not(:last-child) {
43
48
  margin-bottom: 16px;
44
49
  }
@@ -1,14 +1,5 @@
1
1
  import React from 'react';
2
- import { NavigationItemModel } from '../../../models';
2
+ import { MobileNavigationProps } from '../../models';
3
3
  import './MobileNavigation.css';
4
- export interface MobileNavigationProps {
5
- className?: string;
6
- isOpened?: boolean;
7
- topItems?: NavigationItemModel[];
8
- bottomItems?: NavigationItemModel[];
9
- activeItemId?: string;
10
- onClose: () => void;
11
- onActiveItemChange: (id?: string) => void;
12
- }
13
4
  declare const MobileNavigation: React.FC<MobileNavigationProps>;
14
5
  export default MobileNavigation;
@@ -1,43 +1,21 @@
1
- import React, { useCallback, useRef } from 'react';
2
- import { Popup, Portal } from '@gravity-ui/uikit';
1
+ import { __rest } from "tslib";
2
+ import React from 'react';
3
+ import { Portal } from '@gravity-ui/uikit';
3
4
  import Foldable from '../../../components/Foldable/Foldable';
4
- import { NavigationItemType } from '../../../models';
5
5
  import { block } from '../../../utils';
6
- import { ItemColumnName } from '../../constants';
7
- import NavigationItem from '../NavigationItem/NavigationItem';
6
+ import { ItemColumnName, NavigationLayout } from '../../models';
7
+ import { NavigationList } from '../NavigationList/NavigationList';
8
8
  import './MobileNavigation.css';
9
9
  const b = block('mobile-navigation');
10
- const MobileNavigationDropdown = ({ data, onItemClick, onToggle, isOpened = false, }) => {
11
- const ref = useRef(null);
12
- return (React.createElement("div", { ref: ref, className: b('dropdown') },
13
- React.createElement(NavigationItem, { data: data, onClick: onToggle, isOpened: isOpened }),
14
- 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 })))))));
15
- };
16
- const MobileNavigationItem = ({ item, index, isOpened, activeItemId, onActiveItemChange, column, onClose, }) => {
17
- const id = `${column}-${index}`;
18
- const isActive = id === activeItemId && isOpened;
19
- const toggleActive = useCallback((e) => {
20
- e.stopPropagation();
21
- if (onActiveItemChange) {
22
- onActiveItemChange(isActive ? undefined : `${column}-${index}`);
23
- }
24
- }, [onActiveItemChange, isActive, column, index]);
25
- const onItemClick = useCallback((e) => {
26
- toggleActive(e);
27
- onClose();
28
- }, [toggleActive, onClose]);
29
- return (React.createElement("li", { key: index, className: b('rows-item') }, item.type === NavigationItemType.Dropdown ? (React.createElement(MobileNavigationDropdown, { data: item, onToggle: toggleActive, isOpened: isActive, onItemClick: onItemClick })) : (React.createElement(NavigationItem, { data: item, onClick: onItemClick }))));
30
- };
31
- const MobileNavigation = (props) => {
10
+ const MobileNavigation = (_a) => {
11
+ var { isOpened, topItems, bottomItems } = _a, props = __rest(_a, ["isOpened", "topItems", "bottomItems"]);
32
12
  if (typeof window === 'undefined') {
33
13
  return null;
34
14
  }
35
- const { isOpened, topItems, bottomItems, activeItemId, onActiveItemChange, onClose } = props;
36
15
  return (React.createElement(Portal, null,
37
16
  React.createElement(Foldable, { key: topItems === null || topItems === void 0 ? void 0 : topItems.length, className: b(), isOpened: Boolean(isOpened) },
38
17
  React.createElement("div", { className: b('wrapper') },
39
- React.createElement("nav", { className: b('nav') },
40
- React.createElement("ul", { className: b('rows') }, topItems === null || topItems === void 0 ? void 0 : topItems.map((link, index) => (React.createElement(MobileNavigationItem, { key: index, item: link, column: ItemColumnName.Top, index: index, isOpened: isOpened, activeItemId: activeItemId, onClose: onClose, onActiveItemChange: onActiveItemChange }))))),
41
- React.createElement("ul", { className: b('rows') }, bottomItems === null || bottomItems === void 0 ? void 0 : bottomItems.map((item, index) => (React.createElement(MobileNavigationItem, { key: index, item: item, column: ItemColumnName.Bottom, index: index, isOpened: isOpened, activeItemId: activeItemId, onClose: onClose, onActiveItemChange: onActiveItemChange }))))))));
18
+ topItems && (React.createElement(NavigationList, Object.assign({ className: b('rows'), items: topItems, column: ItemColumnName.Top, menuLayout: NavigationLayout.Mobile }, props))),
19
+ bottomItems && (React.createElement(NavigationList, Object.assign({ className: b('rows'), items: bottomItems, column: ItemColumnName.Bottom, menuLayout: NavigationLayout.Mobile }, props)))))));
42
20
  };
43
21
  export default MobileNavigation;
@@ -1,20 +1,15 @@
1
1
  /* use this for style redefinitions to awoid problems with
2
2
  unpredictable css rules order in build */
3
3
  .pc-navigation {
4
- font-size: var(--yc-text-body-2-font-size);
5
- line-height: var(--yc-text-body-2-line-height);
6
- }
7
- .pc-navigation__links {
8
- position: relative;
4
+ position: sticky;
5
+ z-index: 98;
6
+ top: 0;
9
7
  display: flex;
8
+ justify-content: center;
10
9
  align-items: center;
11
- margin: 0;
12
- padding: 0;
13
- list-style: none;
14
- }
15
- .pc-navigation__links-item {
16
- position: relative;
10
+ height: var(--header-height);
11
+ background-color: var(--yc-color-base-background);
17
12
  }
18
- .pc-navigation__links-item:not(:last-child) {
19
- margin-right: 20px;
13
+ .pc-navigation_with-border {
14
+ box-shadow: inset 0 -1px 0 var(--yc-color-line-generic);
20
15
  }
@@ -1,12 +1,9 @@
1
1
  import React from 'react';
2
- import { NavigationItemModel } from '../../../models/navigation';
2
+ import { HeaderData, ThemedNavigationLogoData } from '../../../models';
3
3
  import './Navigation.css';
4
4
  export interface NavigationProps {
5
- links: NavigationItemModel[];
6
- activeItemId?: string;
7
- className?: string;
8
- highlightActiveItem?: boolean;
9
- onActiveItemChange: (id?: string) => void;
5
+ logo: ThemedNavigationLogoData;
6
+ data: HeaderData;
10
7
  }
11
- declare const Navigation: React.FC<NavigationProps>;
8
+ export declare const Navigation: React.FC<NavigationProps>;
12
9
  export default Navigation;
@@ -1,21 +1,41 @@
1
- import React, { useCallback, useContext, useEffect } from 'react';
2
- import OverflowScroller from '../../../components/OverflowScroller/OverflowScroller';
3
- import { LocationContext } from '../../../context/locationContext';
1
+ import React, { useEffect, useMemo, useState } from 'react';
2
+ import _ from 'lodash';
3
+ import OutsideClick from '../../../components/OutsideClick/OutsideClick';
4
+ import { Col, Grid, Row } from '../../../grid';
4
5
  import { block } from '../../../utils';
5
- import { ItemColumnName } from '../../constants';
6
- import { NavigationListItem } from '../NavigationListItem/NavigationListItem';
6
+ import { getNavigationItemWithIconSize } from '../../utils';
7
+ import DesktopNavigation from '../DesktopNavigation/DesktopNavigation';
8
+ import MobileNavigation from '../MobileNavigation/MobileNavigation';
7
9
  import './Navigation.css';
8
10
  const b = block('navigation');
9
- const Navigation = ({ className, onActiveItemChange, links, activeItemId, }) => {
10
- const { asPath, pathname } = useContext(LocationContext);
11
- const hidePopup = useCallback(() => {
12
- onActiveItemChange();
13
- }, [onActiveItemChange]);
11
+ export const Navigation = ({ data, logo }) => {
12
+ const { leftItems, rightItems, iconSize = 20, withBorder = false } = data;
13
+ const [isSidebarOpened, setIsSidebarOpened] = useState(false);
14
+ const [activeItemId, setActiveItemId] = useState(undefined);
15
+ const [showBorder, setShowBorder] = useState(withBorder);
16
+ const getNavigationItem = getNavigationItemWithIconSize(iconSize);
17
+ const leftItemsWithIconSize = useMemo(() => leftItems.map(getNavigationItem), [getNavigationItem, leftItems]);
18
+ const rightItemsWithIconSize = useMemo(() => rightItems === null || rightItems === void 0 ? void 0 : rightItems.map(getNavigationItem), [getNavigationItem, rightItems]);
19
+ const onActiveItemChange = (id) => {
20
+ setActiveItemId(id);
21
+ };
22
+ const onSidebarOpenedChange = (isOpen) => setIsSidebarOpened(isOpen);
14
23
  useEffect(() => {
15
- hidePopup();
16
- }, [hidePopup, asPath, pathname]);
17
- return (React.createElement(OverflowScroller, { className: b(null, className), onScrollStart: hidePopup },
18
- React.createElement("nav", null,
19
- React.createElement("ul", { className: b('links') }, links.map((link, index) => (React.createElement(NavigationListItem, { key: index, className: b('links-item'), item: link, index: index, activeItemId: activeItemId, hidePopup: hidePopup, column: ItemColumnName.Left, onActiveItemChange: onActiveItemChange })))))));
24
+ const showBorderOnScroll = () => {
25
+ if (!showBorder) {
26
+ setShowBorder(window.scrollY > 0);
27
+ }
28
+ };
29
+ const scrollHandler = _.debounce(showBorderOnScroll, 20);
30
+ window.addEventListener('scroll', scrollHandler, { passive: true });
31
+ return () => window.removeEventListener('scroll', scrollHandler);
32
+ });
33
+ return (React.createElement(Grid, { className: b({ 'with-border': showBorder }) },
34
+ React.createElement(Row, null,
35
+ React.createElement(Col, null,
36
+ React.createElement("nav", null,
37
+ React.createElement(DesktopNavigation, { logo: logo, activeItemId: activeItemId, onActiveItemChange: onActiveItemChange, leftItemsWithIconSize: leftItemsWithIconSize, rightItemsWithIconSize: rightItemsWithIconSize, isSidebarOpened: isSidebarOpened, onSidebarOpenedChange: onSidebarOpenedChange }),
38
+ React.createElement(OutsideClick, { onOutsideClick: () => onSidebarOpenedChange(false) },
39
+ React.createElement(MobileNavigation, { topItems: leftItems, bottomItems: rightItems, isOpened: isSidebarOpened, activeItemId: activeItemId, onActiveItemChange: onActiveItemChange })))))));
20
40
  };
21
41
  export default Navigation;
@@ -0,0 +1,28 @@
1
+ /* use this for style redefinitions to awoid problems with
2
+ unpredictable css rules order in build */
3
+ .pc-navigation-item {
4
+ cursor: pointer;
5
+ outline: none;
6
+ color: inherit;
7
+ text-decoration: none;
8
+ }
9
+ .pc-navigation-item:last-child {
10
+ margin-bottom: 0;
11
+ }
12
+ .utilityfocus .pc-navigation-item:focus {
13
+ outline: 2px solid #ffdb4d;
14
+ }
15
+ .pc-navigation-item__content:hover, .pc-navigation-item__content:active {
16
+ color: var(--yc-color-text-link);
17
+ }
18
+ .pc-navigation-item_menu-layout_desktop {
19
+ height: var(--header-height);
20
+ line-height: var(--header-height);
21
+ margin-bottom: 0;
22
+ }
23
+ .pc-navigation-item_menu-layout_mobile {
24
+ margin-bottom: 24px;
25
+ }
26
+ .pc-navigation-item_menu-layout_dropdown {
27
+ margin-bottom: 0;
28
+ }
@@ -1,10 +1,5 @@
1
- import React, { MouseEventHandler } from 'react';
2
- import { NavigationItemData } from '../../../models';
3
- export interface NavigationItemProps {
4
- data: NavigationItemData;
5
- className?: string;
6
- onClick?: MouseEventHandler;
7
- isOpened?: boolean;
8
- }
9
- declare const NavigationItem: React.ForwardRefExoticComponent<NavigationItemProps & React.RefAttributes<HTMLElement>>;
1
+ import React from 'react';
2
+ import { NavigationItemProps } from '../../models';
3
+ import './NavigationItem.css';
4
+ declare const NavigationItem: React.FC<NavigationItemProps>;
10
5
  export default NavigationItem;
@@ -1,12 +1,16 @@
1
1
  import { __rest } from "tslib";
2
2
  import React, { useMemo } from 'react';
3
+ import { omit } from 'lodash';
3
4
  import { BlockIdContext } from '../../../context/blockIdContext';
4
5
  import { NavigationItemType } from '../../../models';
6
+ import { block } from '../../../utils';
5
7
  import SocialIcon from '../SocialIcon/SocialIcon';
6
8
  import { GithubButton } from './components/GithubButton/GithubButton';
7
9
  import { NavigationButton } from './components/NavigationButton/NavigationButton';
8
10
  import { NavigationDropdown } from './components/NavigationDropdown/NavigationDropdown';
9
11
  import { NavigationLink } from './components/NavigationLink/NavigationLink';
12
+ import './NavigationItem.css';
13
+ const b = block('navigation-item');
10
14
  const ANALYTICS_ID = 'navigation';
11
15
  //todo: add types support form component in map
12
16
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -17,13 +21,19 @@ const NavigationItemsMap = {
17
21
  [NavigationItemType.Link]: NavigationLink,
18
22
  [NavigationItemType.GithubButton]: GithubButton,
19
23
  };
20
- const NavigationItem = React.forwardRef((_a, ref) => {
21
- var { data, className } = _a, props = __rest(_a, ["data", "className"]);
24
+ const NavigationItem = (_a) => {
25
+ var { data, className, menuLayout } = _a, props = __rest(_a, ["data", "className", "menuLayout"]);
22
26
  const { type = NavigationItemType.Link } = data;
23
27
  const Component = NavigationItemsMap[type];
24
- const componentProps = useMemo(() => (Object.assign(Object.assign(Object.assign({ className }, data), props), { ref })), [className, data, props, ref]);
28
+ const componentProps = useMemo(() => {
29
+ const componentProperties = Object.assign(Object.assign({}, data), props);
30
+ if (type !== NavigationItemType.Dropdown) {
31
+ return omit(componentProperties, 'hidePopup', 'isActive');
32
+ }
33
+ return componentProperties;
34
+ }, [data, props, type]);
25
35
  return (React.createElement(BlockIdContext.Provider, { value: ANALYTICS_ID },
26
- React.createElement(Component, Object.assign({}, componentProps))));
27
- });
28
- NavigationItem.displayName = 'NavigationItem';
36
+ React.createElement("li", { className: b({ 'menu-layout': menuLayout }, className) },
37
+ React.createElement(Component, Object.assign({}, componentProps, { className: b('content') })))));
38
+ };
29
39
  export default NavigationItem;
@@ -1,5 +1,5 @@
1
1
  import { NavigationGithubButton } from '../../../../../models';
2
- import { NavigationItemProps } from '../../NavigationItem';
2
+ import { NavigationItemProps } from '../../../../models';
3
3
  import './GithubButton.css';
4
4
  type NavigationGithubButtonProps = NavigationItemProps & NavigationGithubButton;
5
5
  export declare const GithubButton: ({ text, url, className, label, size, icon, }: NavigationGithubButtonProps) => JSX.Element;
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { ButtonProps } from '../../../../../models';
3
- import { NavigationItemProps } from '../../NavigationItem';
3
+ import { NavigationItemProps } from '../../../../models';
4
4
  import './NavigationButton.css';
5
5
  type NavigationButtonProps = Pick<NavigationItemProps, 'className'> & ButtonProps;
6
6
  export declare const NavigationButton: React.FC<NavigationButtonProps>;
@@ -1,5 +1,6 @@
1
- import React from 'react';
2
- import { DropdownItemData } from '../../../../../models';
3
- import { NavigationItemProps } from '../../NavigationItem';
1
+ import { NavigationDropdownItem } from '../../../../../models';
2
+ import { NavigationItemProps } from '../../../../models';
4
3
  import './NavigationDropdown.css';
5
- export declare const NavigationDropdown: React.ForwardRefExoticComponent<NavigationItemProps & DropdownItemData & React.RefAttributes<HTMLElement>>;
4
+ type NavigationDropdownProps = NavigationItemProps & NavigationDropdownItem;
5
+ export declare const NavigationDropdown: ({ text, icon, className, iconSize, hidePopup, items, isActive, ...props }: NavigationDropdownProps) => JSX.Element;
6
+ export {};