@gravity-ui/page-constructor 2.6.0 → 2.8.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 (54) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/build/cjs/components/BackgroundMedia/BackgroundMedia.css +8 -0
  3. package/build/cjs/components/BackgroundMedia/BackgroundMedia.d.ts +2 -6
  4. package/build/cjs/components/BackgroundMedia/BackgroundMedia.js +2 -2
  5. package/build/cjs/containers/PageConstructor/PageConstructor.js +1 -1
  6. package/build/cjs/containers/PageConstructor/components/ConstructorItem/ConstructorItem.d.ts +2 -2
  7. package/build/cjs/containers/PageConstructor/components/ConstructorItem/ConstructorItem.js +2 -2
  8. package/build/cjs/models/constructor-items/common.d.ts +5 -0
  9. package/build/cjs/navigation/components/Header/Header.css +0 -12
  10. package/build/cjs/navigation/components/Navigation/Navigation.css +0 -12
  11. package/build/cjs/navigation/components/Navigation/Navigation.js +3 -32
  12. package/build/cjs/navigation/components/NavigationDropdownItem/NavigationDropdownItem.d.ts +1 -1
  13. package/build/cjs/navigation/components/NavigationDropdownItem/NavigationDropdownItem.js +4 -3
  14. package/build/cjs/navigation/components/NavigationItem/NavigationItem.d.ts +1 -1
  15. package/build/cjs/navigation/components/NavigationItem/NavigationItem.js +4 -3
  16. package/build/cjs/navigation/components/NavigationItem/components/NavigationDropdown/NavigationDropdown.d.ts +1 -3
  17. package/build/cjs/navigation/components/NavigationItem/components/NavigationDropdown/NavigationDropdown.js +4 -4
  18. package/build/cjs/navigation/components/NavigationListItem/NavigationListItem.css +16 -0
  19. package/build/cjs/navigation/components/NavigationListItem/NavigationListItem.d.ts +1 -4
  20. package/build/cjs/navigation/components/NavigationListItem/NavigationListItem.js +5 -7
  21. package/build/cjs/navigation/components/NavigationPopup/NavigationPopup.css +2 -5
  22. package/build/cjs/navigation/components/NavigationPopup/NavigationPopup.d.ts +2 -1
  23. package/build/cjs/navigation/components/NavigationPopup/NavigationPopup.js +8 -34
  24. package/build/cjs/schema/index.d.ts +3 -0
  25. package/build/cjs/schema/validators/common.d.ts +3 -0
  26. package/build/cjs/schema/validators/common.js +2 -0
  27. package/build/esm/components/BackgroundMedia/BackgroundMedia.css +8 -0
  28. package/build/esm/components/BackgroundMedia/BackgroundMedia.d.ts +2 -6
  29. package/build/esm/components/BackgroundMedia/BackgroundMedia.js +2 -2
  30. package/build/esm/containers/PageConstructor/PageConstructor.js +2 -2
  31. package/build/esm/containers/PageConstructor/components/ConstructorItem/ConstructorItem.d.ts +2 -2
  32. package/build/esm/containers/PageConstructor/components/ConstructorItem/ConstructorItem.js +2 -2
  33. package/build/esm/models/constructor-items/common.d.ts +5 -0
  34. package/build/esm/navigation/components/Header/Header.css +0 -12
  35. package/build/esm/navigation/components/Navigation/Navigation.css +0 -12
  36. package/build/esm/navigation/components/Navigation/Navigation.js +4 -33
  37. package/build/esm/navigation/components/NavigationDropdownItem/NavigationDropdownItem.d.ts +1 -1
  38. package/build/esm/navigation/components/NavigationDropdownItem/NavigationDropdownItem.js +5 -4
  39. package/build/esm/navigation/components/NavigationItem/NavigationItem.d.ts +1 -1
  40. package/build/esm/navigation/components/NavigationItem/NavigationItem.js +4 -3
  41. package/build/esm/navigation/components/NavigationItem/components/NavigationDropdown/NavigationDropdown.d.ts +1 -3
  42. package/build/esm/navigation/components/NavigationItem/components/NavigationDropdown/NavigationDropdown.js +4 -3
  43. package/build/esm/navigation/components/NavigationListItem/NavigationListItem.css +16 -0
  44. package/build/esm/navigation/components/NavigationListItem/NavigationListItem.d.ts +1 -4
  45. package/build/esm/navigation/components/NavigationListItem/NavigationListItem.js +5 -7
  46. package/build/esm/navigation/components/NavigationPopup/NavigationPopup.css +2 -5
  47. package/build/esm/navigation/components/NavigationPopup/NavigationPopup.d.ts +2 -1
  48. package/build/esm/navigation/components/NavigationPopup/NavigationPopup.js +9 -35
  49. package/build/esm/schema/index.d.ts +3 -0
  50. package/build/esm/schema/validators/common.d.ts +3 -0
  51. package/build/esm/schema/validators/common.js +2 -0
  52. package/package.json +1 -1
  53. package/server/models/constructor-items/common.d.ts +5 -0
  54. package/styles/mixins.scss +0 -11
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.8.0](https://github.com/gravity-ui/page-constructor/compare/v2.7.0...v2.8.0) (2023-04-11)
4
+
5
+
6
+ ### Features
7
+
8
+ * **BackgroundMedia:** add fullWidthMedia for BackgroundMedia ([#281](https://github.com/gravity-ui/page-constructor/issues/281)) ([5cd19b8](https://github.com/gravity-ui/page-constructor/commit/5cd19b8d4fcbf56b854a49c88b794a056d4e3295))
9
+
10
+ ## [2.7.0](https://github.com/gravity-ui/page-constructor/compare/v2.6.0...v2.7.0) (2023-04-06)
11
+
12
+
13
+ ### Features
14
+
15
+ * add default analytics context to header block ([#289](https://github.com/gravity-ui/page-constructor/issues/289)) ([c1b8e45](https://github.com/gravity-ui/page-constructor/commit/c1b8e45423e7d8e2bd7daa108a8b296aebb811ef))
16
+
3
17
  ## [2.6.0](https://github.com/gravity-ui/page-constructor/compare/v2.5.0...v2.6.0) (2023-04-05)
4
18
 
5
19
 
@@ -12,6 +12,14 @@ unpredictable css rules order in build */
12
12
  text-align: center;
13
13
  height: 100%;
14
14
  }
15
+ .pc-BackgroundMedia__media_full-width-media {
16
+ max-width: none;
17
+ }
18
+ .pc-BackgroundMedia__media_full-width-media .pc-BackgroundMedia__video video {
19
+ height: 100%;
20
+ width: 100%;
21
+ object-fit: cover;
22
+ }
15
23
  .pc-BackgroundMedia__image {
16
24
  height: 100%;
17
25
  width: 100%;
@@ -1,7 +1,3 @@
1
- import { Animatable, MediaProps } from '../../models';
2
- export interface FullProps extends MediaProps, Animatable {
3
- className?: string;
4
- mediaClassName?: string;
5
- }
6
- declare const BackgroundMedia: ({ className, color, animated, parallax, video, mediaClassName, ...props }: FullProps) => JSX.Element;
1
+ import { BackgroundMediaProps } from '../../models';
2
+ declare const BackgroundMedia: ({ className, color, animated, parallax, video, mediaClassName, fullWidthMedia, ...props }: BackgroundMediaProps) => JSX.Element;
7
3
  export default BackgroundMedia;
@@ -8,10 +8,10 @@ const AnimateBlock_1 = tslib_1.__importDefault(require("../AnimateBlock/AnimateB
8
8
  const Media_1 = tslib_1.__importDefault(require("../Media/Media"));
9
9
  const b = (0, utils_1.block)('BackgroundMedia');
10
10
  const BackgroundMedia = (_a) => {
11
- var { className, color, animated, parallax = true, video, mediaClassName } = _a, props = tslib_1.__rest(_a, ["className", "color", "animated", "parallax", "video", "mediaClassName"]);
11
+ var { className, color, animated, parallax = true, video, mediaClassName, fullWidthMedia } = _a, props = tslib_1.__rest(_a, ["className", "color", "animated", "parallax", "video", "mediaClassName", "fullWidthMedia"]);
12
12
  const isMobile = (0, react_1.useContext)(mobileContext_1.MobileContext);
13
13
  return (react_1.default.createElement(AnimateBlock_1.default, { className: b(null, className), style: { backgroundColor: color }, animate: animated },
14
- react_1.default.createElement(Media_1.default, Object.assign({ className: b('media', mediaClassName), imageClassName: b('image'), videoClassName: b('video'), isBackground: true }, Object.assign({ height: 720, color,
14
+ react_1.default.createElement(Media_1.default, Object.assign({ className: b('media', { 'full-width-media': fullWidthMedia }, mediaClassName), imageClassName: b('image'), videoClassName: b('video'), isBackground: true }, Object.assign({ height: 720, color,
15
15
  parallax, video: isMobile ? undefined : video }, props)))));
16
16
  };
17
17
  exports.default = BackgroundMedia;
@@ -42,7 +42,7 @@ const Constructor = (props) => {
42
42
  themedBackground && (react_1.default.createElement(BackgroundMedia_1.default, Object.assign({}, themedBackground, { className: b('background') }))),
43
43
  react_1.default.createElement(Layout_1.default, { navigation: navigation },
44
44
  renderMenu && renderMenu(),
45
- header && react_1.default.createElement(ConstructorItem_1.ConstructorHeader, { data: header }),
45
+ header && (react_1.default.createElement(ConstructorItem_1.ConstructorHeader, { data: header, blockKey: models_1.BlockType.HeaderBlock })),
46
46
  react_1.default.createElement(grid_1.Grid, null,
47
47
  restBlocks && (react_1.default.createElement(ConstructorRow_1.ConstructorRow, null,
48
48
  react_1.default.createElement(ConstructorBlocks_1.ConstructorBlocks, { items: restBlocks }))),
@@ -1,7 +1,7 @@
1
1
  import { ConstructorItem as ConstructorItemType, WithChildren } from '../../../../models';
2
2
  export interface ConstructorItemProps {
3
3
  data: ConstructorItemType;
4
- blockKey?: string;
4
+ blockKey: string;
5
5
  }
6
- export declare const ConstructorItem: ({ data, blockKey, children, }: WithChildren<ConstructorItemProps>) => JSX.Element;
6
+ export declare const ConstructorItem: ({ data, blockKey, children }: WithChildren<ConstructorItemProps>) => JSX.Element;
7
7
  export declare const ConstructorHeader: ({ data, blockKey, }: Pick<ConstructorItemProps, 'data' | 'blockKey'>) => JSX.Element;
@@ -5,7 +5,7 @@ const tslib_1 = require("tslib");
5
5
  const react_1 = tslib_1.__importStar(require("react"));
6
6
  const blockIdContext_1 = require("../../../../context/blockIdContext");
7
7
  const innerContext_1 = require("../../../../context/innerContext");
8
- const ConstructorItem = ({ data, blockKey = '', children, }) => {
8
+ const ConstructorItem = ({ data, blockKey, children }) => {
9
9
  const { itemMap } = (0, react_1.useContext)(innerContext_1.InnerContext);
10
10
  const { type } = data, rest = tslib_1.__rest(data, ["type"]);
11
11
  const Component = itemMap[type];
@@ -13,5 +13,5 @@ const ConstructorItem = ({ data, blockKey = '', children, }) => {
13
13
  react_1.default.createElement(Component, Object.assign({}, rest), children)));
14
14
  };
15
15
  exports.ConstructorItem = ConstructorItem;
16
- const ConstructorHeader = ({ data, blockKey = '', }) => (react_1.default.createElement(exports.ConstructorItem, { data: data, key: data.type, blockKey: blockKey }));
16
+ const ConstructorHeader = ({ data, blockKey, }) => (react_1.default.createElement(exports.ConstructorItem, { data: data, key: data.type, blockKey: blockKey }));
17
17
  exports.ConstructorHeader = ConstructorHeader;
@@ -188,6 +188,11 @@ export interface MediaComponentDataLensProps {
188
188
  export interface MediaProps extends Animatable, Partial<MediaComponentDataLensProps>, Partial<MediaComponentYoutubeProps>, Partial<MediaComponentImageProps>, Partial<MediaComponentVideoProps> {
189
189
  color?: string;
190
190
  }
191
+ export interface BackgroundMediaProps extends MediaProps, Animatable {
192
+ fullWidthMedia?: boolean;
193
+ className?: string;
194
+ mediaClassName?: string;
195
+ }
191
196
  export type Coordinate = number[];
192
197
  export interface MapBaseProps {
193
198
  zoom?: number;
@@ -69,18 +69,6 @@ unpredictable css rules order in build */
69
69
  }
70
70
  .pc-header__buttons-item {
71
71
  position: relative;
72
- height: var(--header-height);
73
- line-height: var(--header-height);
74
- cursor: pointer;
75
- outline: none;
76
- color: inherit;
77
- text-decoration: none;
78
- }
79
- .utilityfocus .pc-header__buttons-item:focus {
80
- outline: 2px solid #ffdb4d;
81
- }
82
- .pc-header__buttons-item:hover, .pc-header__buttons-item:active {
83
- color: var(--yc-color-text-link);
84
72
  }
85
73
  .pc-header__buttons-item:not(:last-child) {
86
74
  margin-right: 20px;
@@ -14,18 +14,6 @@ unpredictable css rules order in build */
14
14
  }
15
15
  .pc-navigation__links-item {
16
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 .pc-navigation__links-item:focus {
25
- outline: 2px solid #ffdb4d;
26
- }
27
- .pc-navigation__links-item:hover, .pc-navigation__links-item:active {
28
- color: var(--yc-color-text-link);
29
17
  }
30
18
  .pc-navigation__links-item:not(:last-child) {
31
19
  margin-right: 20px;
@@ -2,51 +2,22 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const react_1 = tslib_1.__importStar(require("react"));
5
- const lodash_1 = tslib_1.__importDefault(require("lodash"));
6
5
  const OverflowScroller_1 = tslib_1.__importDefault(require("../../../components/OverflowScroller/OverflowScroller"));
7
6
  const locationContext_1 = require("../../../context/locationContext");
8
7
  const utils_1 = require("../../../utils");
9
8
  const constants_1 = require("../../constants");
10
9
  const NavigationListItem_1 = require("../NavigationListItem/NavigationListItem");
11
10
  const b = (0, utils_1.block)('navigation');
12
- const EVENT_HANDLE_DELAY = 100;
13
- const Navigation = ({ className, onActiveItemChange, links, activeItemId, highlightActiveItem, }) => {
11
+ const Navigation = ({ className, onActiveItemChange, links, activeItemId, }) => {
14
12
  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
13
  const hidePopup = (0, react_1.useCallback)(() => {
19
14
  onActiveItemChange();
20
15
  }, [onActiveItemChange]);
21
- const calculateItemPositions = (0, react_1.useCallback)(() => {
22
- if (itemRefs.current.length) {
23
- const currentItemPositions = itemRefs.current.map((itemRef) => (itemRef && itemRef.getBoundingClientRect().left) || 0);
24
- setItemPosition(currentItemPositions);
25
- }
26
- }, []);
27
- (0, react_1.useEffect)(() => {
28
- const debouncedCalculateItemPositions = lodash_1.default.debounce(calculateItemPositions, EVENT_HANDLE_DELAY);
29
- const debouncedCalculateOnScroll = lodash_1.default.debounce(() => {
30
- const curLeftScroll = window.pageXOffset;
31
- if (curLeftScroll !== lastLeftScroll) {
32
- setLastLeftScroll(window.pageXOffset);
33
- calculateItemPositions();
34
- }
35
- }, EVENT_HANDLE_DELAY);
36
- calculateItemPositions();
37
- setLastLeftScroll(window.pageXOffset);
38
- window.addEventListener('resize', debouncedCalculateItemPositions);
39
- window.addEventListener('scroll', debouncedCalculateOnScroll);
40
- return () => {
41
- window.removeEventListener(`resize`, debouncedCalculateItemPositions);
42
- window.removeEventListener('scroll', debouncedCalculateOnScroll);
43
- };
44
- }, [calculateItemPositions, itemRefs, lastLeftScroll]);
45
16
  (0, react_1.useEffect)(() => {
46
17
  hidePopup();
47
18
  }, [hidePopup, asPath, pathname]);
48
- return (react_1.default.createElement(OverflowScroller_1.default, { className: b(null, className), onScrollStart: hidePopup, onScrollEnd: calculateItemPositions },
19
+ return (react_1.default.createElement(OverflowScroller_1.default, { className: b(null, className), onScrollStart: hidePopup },
49
20
  react_1.default.createElement("nav", null,
50
- react_1.default.createElement("ul", { className: b('links') }, links.map((link, index) => (react_1.default.createElement(NavigationListItem_1.NavigationListItem, { key: index, className: b('links-item'), item: link, itemRefs: itemRefs, index: index, activeItemId: activeItemId, highlightActiveItem: highlightActiveItem, hidePopup: hidePopup, itemPositions: itemPositions, column: constants_1.ItemColumnName.Left, onActiveItemChange: onActiveItemChange })))))));
21
+ react_1.default.createElement("ul", { className: b('links') }, links.map((link, index) => (react_1.default.createElement(NavigationListItem_1.NavigationListItem, { key: index, className: b('links-item'), item: link, index: index, activeItemId: activeItemId, hidePopup: hidePopup, column: constants_1.ItemColumnName.Left, onActiveItemChange: onActiveItemChange })))))));
51
22
  };
52
23
  exports.default = Navigation;
@@ -1,10 +1,10 @@
1
1
  import React, { MouseEventHandler } from 'react';
2
2
  import { NavigationDropdownItem } from '../../../models';
3
3
  export interface NavigationDropdownProps {
4
+ className?: string;
4
5
  data: NavigationDropdownItem;
5
6
  onClick: MouseEventHandler;
6
7
  isActive: boolean;
7
- position: number;
8
8
  hidePopup: () => void;
9
9
  }
10
10
  declare const NavigationDropdown: React.FC<NavigationDropdownProps>;
@@ -5,10 +5,11 @@ const react_1 = tslib_1.__importStar(require("react"));
5
5
  const models_1 = require("../../../models");
6
6
  const NavigationItem_1 = tslib_1.__importDefault(require("../NavigationItem/NavigationItem"));
7
7
  const NavigationPopup_1 = tslib_1.__importDefault(require("../NavigationPopup/NavigationPopup"));
8
- const NavigationDropdown = ({ data, isActive, position, hidePopup, onClick, }) => {
8
+ const NavigationDropdown = ({ className, data, isActive, hidePopup, onClick, }) => {
9
+ const anchorRef = (0, react_1.useRef)(null);
9
10
  const { text, icon, items } = data, popupProps = tslib_1.__rest(data, ["text", "icon", "items"]);
10
11
  return (react_1.default.createElement(react_1.Fragment, null,
11
- react_1.default.createElement(NavigationItem_1.default, { onClick: onClick, isOpened: isActive, data: { text, type: models_1.NavigationItemType.Dropdown, icon } }),
12
- isActive && (react_1.default.createElement(NavigationPopup_1.default, Object.assign({ left: position, onClose: hidePopup, items: items }, popupProps)))));
12
+ react_1.default.createElement(NavigationItem_1.default, { className: className, ref: anchorRef, onClick: onClick, isOpened: isActive, data: { text, type: models_1.NavigationItemType.Dropdown, icon } }),
13
+ react_1.default.createElement(NavigationPopup_1.default, Object.assign({ open: isActive, onClose: hidePopup, items: items, anchorRef: anchorRef }, popupProps))));
13
14
  };
14
15
  exports.default = NavigationDropdown;
@@ -6,5 +6,5 @@ export interface NavigationItemProps {
6
6
  onClick?: MouseEventHandler;
7
7
  isOpened?: boolean;
8
8
  }
9
- declare const NavigationItem: React.FC<NavigationItemProps>;
9
+ declare const NavigationItem: React.ForwardRefExoticComponent<NavigationItemProps & React.RefAttributes<HTMLElement>>;
10
10
  export default NavigationItem;
@@ -19,12 +19,13 @@ const NavigationItemsMap = {
19
19
  [models_1.NavigationItemType.Link]: NavigationLink_1.NavigationLink,
20
20
  [models_1.NavigationItemType.GithubButton]: GithubButton_1.GithubButton,
21
21
  };
22
- const NavigationItem = (_a) => {
22
+ const NavigationItem = react_1.default.forwardRef((_a, ref) => {
23
23
  var { data, className } = _a, props = tslib_1.__rest(_a, ["data", "className"]);
24
24
  const { type = models_1.NavigationItemType.Link } = data;
25
25
  const Component = NavigationItemsMap[type];
26
- const componentProps = (0, react_1.useMemo)(() => (Object.assign(Object.assign({ className }, data), props)), [className, data, props]);
26
+ const componentProps = (0, react_1.useMemo)(() => (Object.assign(Object.assign(Object.assign({ className }, data), props), { ref })), [className, data, props, ref]);
27
27
  return (react_1.default.createElement(blockIdContext_1.BlockIdContext.Provider, { value: ANALYTICS_ID },
28
28
  react_1.default.createElement(Component, Object.assign({}, componentProps))));
29
- };
29
+ });
30
+ NavigationItem.displayName = 'NavigationItem';
30
31
  exports.default = NavigationItem;
@@ -1,6 +1,4 @@
1
1
  import React from 'react';
2
2
  import { DropdownItemData } from '../../../../../models';
3
3
  import { NavigationItemProps } from '../../NavigationItem';
4
- type NavigationDropdownProps = NavigationItemProps & DropdownItemData;
5
- export declare const NavigationDropdown: React.FC<NavigationDropdownProps>;
6
- export {};
4
+ export declare const NavigationDropdown: React.ForwardRefExoticComponent<NavigationItemProps & DropdownItemData & React.RefAttributes<HTMLElement>>;
@@ -9,11 +9,11 @@ const utils_2 = require("../../../../../utils");
9
9
  const ContentWrapper_1 = require("../ContentWrapper/ContentWrapper");
10
10
  const b = (0, utils_2.block)('navigation-dropdown');
11
11
  const TOGGLE_ARROW_SIZE = 12;
12
- const NavigationDropdown = (_a) => {
12
+ exports.NavigationDropdown = react_1.default.forwardRef((_a, ref) => {
13
13
  var { text, icon, isOpened, className } = _a, props = tslib_1.__rest(_a, ["text", "icon", "isOpened", "className"]);
14
14
  const iconData = icon && (0, utils_1.getMediaImage)(icon);
15
- return (react_1.default.createElement("span", Object.assign({}, props, { className: b(null, className) }),
15
+ return (react_1.default.createElement("span", Object.assign({ ref: ref }, props, { className: b(null, className) }),
16
16
  react_1.default.createElement(ContentWrapper_1.ContentWrapper, { text: text, icon: iconData }),
17
17
  react_1.default.createElement(components_1.ToggleArrow, { className: b('arrow'), size: TOGGLE_ARROW_SIZE, type: 'vertical', iconType: "navigation", open: isOpened })));
18
- };
19
- exports.NavigationDropdown = NavigationDropdown;
18
+ });
19
+ exports.NavigationDropdown.displayName = 'NavigationDropdown';
@@ -1,3 +1,19 @@
1
+ /* use this for style redefinitions to awoid problems with
2
+ unpredictable css rules order in build */
3
+ .pc-navigation-list-item {
4
+ height: var(--header-height);
5
+ line-height: var(--header-height);
6
+ cursor: pointer;
7
+ outline: none;
8
+ color: inherit;
9
+ text-decoration: none;
10
+ }
11
+ .utilityfocus .pc-navigation-list-item:focus {
12
+ outline: 2px solid #ffdb4d;
13
+ }
14
+ .pc-navigation-list-item__content:hover, .pc-navigation-list-item__content:active {
15
+ color: var(--yc-color-text-link);
16
+ }
1
17
  .pc-navigation-list-item__slider-container {
2
18
  position: absolute;
3
19
  right: 0;
@@ -1,4 +1,3 @@
1
- import React from 'react';
2
1
  import { ClassNameProps, NavigationItemModel } from '../../../models';
3
2
  import { ItemColumnName } from '../../constants';
4
3
  type NavigationListItemProps = {
@@ -6,11 +5,9 @@ type NavigationListItemProps = {
6
5
  index: number;
7
6
  column: ItemColumnName;
8
7
  activeItemId?: string;
9
- itemPositions?: number[];
10
- itemRefs?: React.MutableRefObject<(HTMLLIElement | null)[]>;
11
8
  highlightActiveItem?: boolean;
12
9
  hidePopup: () => void;
13
10
  onActiveItemChange: (id?: string) => void;
14
11
  } & ClassNameProps;
15
- export declare const NavigationListItem: ({ item, itemRefs, className, index, activeItemId, highlightActiveItem, hidePopup, itemPositions, column, onActiveItemChange, }: NavigationListItemProps) => JSX.Element;
12
+ export declare const NavigationListItem: ({ item, className, index, activeItemId, highlightActiveItem, hidePopup, column, onActiveItemChange, }: NavigationListItemProps) => JSX.Element;
16
13
  export {};
@@ -2,16 +2,14 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NavigationListItem = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const react_1 = tslib_1.__importStar(require("react"));
5
+ const react_1 = tslib_1.__importDefault(require("react"));
6
6
  const models_1 = require("../../../models");
7
7
  const utils_1 = require("../../../utils");
8
8
  const utils_2 = require("../../utils");
9
9
  const NavigationDropdownItem_1 = tslib_1.__importDefault(require("../NavigationDropdownItem/NavigationDropdownItem"));
10
10
  const NavigationItem_1 = tslib_1.__importDefault(require("../NavigationItem/NavigationItem"));
11
- const b = (0, utils_1.block)('navigation');
12
- const NavigationListItem = ({ item, itemRefs, className, index, activeItemId, highlightActiveItem, hidePopup, itemPositions, column, onActiveItemChange, }) => {
13
- var _a;
14
- const ref = (0, react_1.useRef)(null);
11
+ const b = (0, utils_1.block)('navigation-list-item');
12
+ const NavigationListItem = ({ item, className, index, activeItemId, highlightActiveItem, hidePopup, column, onActiveItemChange, }) => {
15
13
  const id = `${column}-${index}`;
16
14
  const isActive = id === activeItemId;
17
15
  const onClick = (0, utils_2.getItemClickHandler)({
@@ -20,8 +18,8 @@ const NavigationListItem = ({ item, itemRefs, className, index, activeItemId, hi
20
18
  activeItemId,
21
19
  onActiveItemChange,
22
20
  });
23
- return (react_1.default.createElement("li", { ref: itemRefs ? (el) => itemRefs.current.push(el) : ref, className: className },
24
- item.type === models_1.NavigationItemType.Dropdown ? (react_1.default.createElement(NavigationDropdownItem_1.default, { data: item, onClick: onClick, isActive: isActive, position: (itemPositions === null || itemPositions === void 0 ? void 0 : itemPositions[index]) || ((_a = ref.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().left) || 0, hidePopup: hidePopup })) : (react_1.default.createElement(NavigationItem_1.default, { data: item, onClick: onClick })),
21
+ return (react_1.default.createElement("li", { className: b(null, className) },
22
+ item.type === models_1.NavigationItemType.Dropdown ? (react_1.default.createElement(NavigationDropdownItem_1.default, { className: b('content'), data: item, onClick: onClick, isActive: isActive, hidePopup: hidePopup })) : (react_1.default.createElement(NavigationItem_1.default, { className: b('content'), data: item, onClick: onClick })),
25
23
  highlightActiveItem && isActive && (react_1.default.createElement("div", { className: b('slider-container') },
26
24
  react_1.default.createElement("div", { className: b('slider') })))));
27
25
  };
@@ -1,11 +1,8 @@
1
1
  /* use this for style redefinitions to awoid problems with
2
2
  unpredictable css rules order in build */
3
3
  .pc-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));
4
+ margin-left: -16px;
5
+ margin-top: -16px;
9
6
  z-index: 101;
10
7
  display: flex;
11
8
  flex-direction: column;
@@ -1,10 +1,11 @@
1
1
  import React from 'react';
2
2
  import { NavigationLinkItem } from '../../../models';
3
3
  export interface NavigationPopupProps {
4
+ open: boolean;
4
5
  items: NavigationLinkItem[];
5
6
  onClose: () => void;
6
- left?: number;
7
7
  className?: string;
8
+ anchorRef: React.RefObject<Element>;
8
9
  }
9
10
  export declare const NavigationPopup: React.FC<NavigationPopupProps>;
10
11
  export default NavigationPopup;
@@ -2,44 +2,18 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NavigationPopup = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const react_1 = tslib_1.__importStar(require("react"));
6
- const lodash_1 = tslib_1.__importDefault(require("lodash"));
5
+ const react_1 = tslib_1.__importDefault(require("react"));
7
6
  const uikit_1 = require("@gravity-ui/uikit");
8
- const components_1 = require("../../../components");
9
7
  const utils_1 = require("../../../utils");
10
8
  const NavigationItem_1 = tslib_1.__importDefault(require("../NavigationItem/NavigationItem"));
11
9
  const b = (0, utils_1.block)('navigation-popup');
12
- const NavigationPopup = ({ items, left, onClose }) => {
13
- const [calculatedLeft, setCalculatedLeft] = (0, react_1.useState)(left);
14
- const popupRef = (0, react_1.useRef)(null);
15
- const calculateLeft = (0, react_1.useCallback)(() => {
16
- if (popupRef && popupRef.current && left) {
17
- const right = left + popupRef.current.offsetWidth;
18
- const docWidth = document.body.clientWidth;
19
- const currentLeft = right > docWidth ? left - (right - docWidth) : left;
20
- setCalculatedLeft(currentLeft);
21
- }
22
- else {
23
- setCalculatedLeft(left);
24
- }
25
- }, [left]);
26
- (0, react_1.useEffect)(() => {
27
- const debounceCalculateLeft = lodash_1.default.debounce(calculateLeft, 100);
28
- calculateLeft();
29
- window.addEventListener('resize', debounceCalculateLeft);
30
- return () => {
31
- window.removeEventListener('resize', debounceCalculateLeft);
32
- };
33
- }, [calculateLeft]);
34
- (0, react_1.useEffect)(() => {
35
- calculateLeft();
36
- }, [calculateLeft, left]);
37
- if (!document || !document.body) {
38
- return null;
39
- }
40
- return (react_1.default.createElement(uikit_1.Portal, null,
41
- react_1.default.createElement("div", { ref: popupRef, className: b(), style: { left: calculatedLeft } },
42
- react_1.default.createElement(components_1.OutsideClick, { onOutsideClick: onClose }, items.map((item) => (react_1.default.createElement(NavigationItem_1.default, { key: item.text, className: b('link'), data: item })))))));
10
+ const OFFSET_RESET = [0, 0];
11
+ const NavigationPopup = ({ anchorRef, items, onClose, className, open, }) => {
12
+ return (react_1.default.createElement(uikit_1.Popup
13
+ // Workaround to recalculate position on every opening. Required for valid position calculation for scrolled header links.
14
+ , {
15
+ // Workaround to recalculate position on every opening. Required for valid position calculation for scrolled header links.
16
+ anchorRef: open ? anchorRef : undefined, className: b(null, className), open: open, onClose: onClose, onOutsideClick: onClose, keepMounted: true, disablePortal: true, strategy: "fixed", placement: "bottom-start", offset: OFFSET_RESET }, items.map((item) => (react_1.default.createElement(NavigationItem_1.default, { key: item.text, className: b('link'), data: item })))));
43
17
  };
44
18
  exports.NavigationPopup = NavigationPopup;
45
19
  exports.default = exports.NavigationPopup;
@@ -209,6 +209,9 @@ export declare function generateDefaultSchema(config?: SchemaCustomConfig): {
209
209
  parallax: {
210
210
  type: string;
211
211
  };
212
+ fullWidthMedia: {
213
+ type: string;
214
+ };
212
215
  animated: {
213
216
  type: string;
214
217
  };
@@ -286,6 +286,9 @@ export declare const BackgroundProps: {
286
286
  parallax: {
287
287
  type: string;
288
288
  };
289
+ fullWidthMedia: {
290
+ type: string;
291
+ };
289
292
  animated: {
290
293
  type: string;
291
294
  };
@@ -156,6 +156,8 @@ exports.BackgroundProps = {
156
156
  enum: ['contain', 'cover'],
157
157
  }, parallax: {
158
158
  type: 'boolean',
159
+ }, fullWidthMedia: {
160
+ type: 'boolean',
159
161
  } }),
160
162
  };
161
163
  exports.LinkProps = {
@@ -12,6 +12,14 @@ unpredictable css rules order in build */
12
12
  text-align: center;
13
13
  height: 100%;
14
14
  }
15
+ .pc-BackgroundMedia__media_full-width-media {
16
+ max-width: none;
17
+ }
18
+ .pc-BackgroundMedia__media_full-width-media .pc-BackgroundMedia__video video {
19
+ height: 100%;
20
+ width: 100%;
21
+ object-fit: cover;
22
+ }
15
23
  .pc-BackgroundMedia__image {
16
24
  height: 100%;
17
25
  width: 100%;
@@ -1,8 +1,4 @@
1
- import { Animatable, MediaProps } from '../../models';
1
+ import { BackgroundMediaProps } from '../../models';
2
2
  import './BackgroundMedia.css';
3
- export interface FullProps extends MediaProps, Animatable {
4
- className?: string;
5
- mediaClassName?: string;
6
- }
7
- declare const BackgroundMedia: ({ className, color, animated, parallax, video, mediaClassName, ...props }: FullProps) => JSX.Element;
3
+ declare const BackgroundMedia: ({ className, color, animated, parallax, video, mediaClassName, fullWidthMedia, ...props }: BackgroundMediaProps) => JSX.Element;
8
4
  export default BackgroundMedia;
@@ -7,10 +7,10 @@ import Media from '../Media/Media';
7
7
  import './BackgroundMedia.css';
8
8
  const b = block('BackgroundMedia');
9
9
  const BackgroundMedia = (_a) => {
10
- var { className, color, animated, parallax = true, video, mediaClassName } = _a, props = __rest(_a, ["className", "color", "animated", "parallax", "video", "mediaClassName"]);
10
+ var { className, color, animated, parallax = true, video, mediaClassName, fullWidthMedia } = _a, props = __rest(_a, ["className", "color", "animated", "parallax", "video", "mediaClassName", "fullWidthMedia"]);
11
11
  const isMobile = useContext(MobileContext);
12
12
  return (React.createElement(AnimateBlock, { className: b(null, className), style: { backgroundColor: color }, animate: animated },
13
- React.createElement(Media, Object.assign({ className: b('media', mediaClassName), imageClassName: b('image'), videoClassName: b('video'), isBackground: true }, Object.assign({ height: 720, color,
13
+ React.createElement(Media, Object.assign({ className: b('media', { 'full-width-media': fullWidthMedia }, mediaClassName), imageClassName: b('image'), videoClassName: b('video'), isBackground: true }, Object.assign({ height: 720, color,
14
14
  parallax, video: isMobile ? undefined : video }, props)))));
15
15
  };
16
16
  export default BackgroundMedia;
@@ -7,7 +7,7 @@ import { AnimateContext } from '../../context/animateContext';
7
7
  import { InnerContext } from '../../context/innerContext';
8
8
  import { ThemeValueContext } from '../../context/theme/ThemeValueContext';
9
9
  import { Grid } from '../../grid';
10
- import { BlockTypes, HeaderBlockTypes, SubBlockTypes, } from '../../models';
10
+ import { BlockType, BlockTypes, HeaderBlockTypes, SubBlockTypes, } from '../../models';
11
11
  import Layout from '../../navigation/containers/Layout/Layout';
12
12
  import { block as cnBlock, getCustomBlockTypes, getCustomHeaderTypes, getCustomItems, getCustomSubBlockTypes, getThemedValue, } from '../../utils';
13
13
  import { ConstructorBlocks } from './components/ConstructorBlocks';
@@ -40,7 +40,7 @@ export const Constructor = (props) => {
40
40
  themedBackground && (React.createElement(BackgroundMedia, Object.assign({}, themedBackground, { className: b('background') }))),
41
41
  React.createElement(Layout, { navigation: navigation },
42
42
  renderMenu && renderMenu(),
43
- header && React.createElement(ConstructorHeader, { data: header }),
43
+ header && (React.createElement(ConstructorHeader, { data: header, blockKey: BlockType.HeaderBlock })),
44
44
  React.createElement(Grid, null,
45
45
  restBlocks && (React.createElement(ConstructorRow, null,
46
46
  React.createElement(ConstructorBlocks, { items: restBlocks }))),
@@ -1,7 +1,7 @@
1
1
  import { ConstructorItem as ConstructorItemType, WithChildren } from '../../../../models';
2
2
  export interface ConstructorItemProps {
3
3
  data: ConstructorItemType;
4
- blockKey?: string;
4
+ blockKey: string;
5
5
  }
6
- export declare const ConstructorItem: ({ data, blockKey, children, }: WithChildren<ConstructorItemProps>) => JSX.Element;
6
+ export declare const ConstructorItem: ({ data, blockKey, children }: WithChildren<ConstructorItemProps>) => JSX.Element;
7
7
  export declare const ConstructorHeader: ({ data, blockKey, }: Pick<ConstructorItemProps, 'data' | 'blockKey'>) => JSX.Element;
@@ -2,11 +2,11 @@ import { __rest } from "tslib";
2
2
  import React, { useContext } from 'react';
3
3
  import { BlockIdContext } from '../../../../context/blockIdContext';
4
4
  import { InnerContext } from '../../../../context/innerContext';
5
- export const ConstructorItem = ({ data, blockKey = '', children, }) => {
5
+ export const ConstructorItem = ({ data, blockKey, children }) => {
6
6
  const { itemMap } = useContext(InnerContext);
7
7
  const { type } = data, rest = __rest(data, ["type"]);
8
8
  const Component = itemMap[type];
9
9
  return (React.createElement(BlockIdContext.Provider, { value: blockKey },
10
10
  React.createElement(Component, Object.assign({}, rest), children)));
11
11
  };
12
- export const ConstructorHeader = ({ data, blockKey = '', }) => (React.createElement(ConstructorItem, { data: data, key: data.type, blockKey: blockKey }));
12
+ export const ConstructorHeader = ({ data, blockKey, }) => (React.createElement(ConstructorItem, { data: data, key: data.type, blockKey: blockKey }));
@@ -188,6 +188,11 @@ export interface MediaComponentDataLensProps {
188
188
  export interface MediaProps extends Animatable, Partial<MediaComponentDataLensProps>, Partial<MediaComponentYoutubeProps>, Partial<MediaComponentImageProps>, Partial<MediaComponentVideoProps> {
189
189
  color?: string;
190
190
  }
191
+ export interface BackgroundMediaProps extends MediaProps, Animatable {
192
+ fullWidthMedia?: boolean;
193
+ className?: string;
194
+ mediaClassName?: string;
195
+ }
191
196
  export type Coordinate = number[];
192
197
  export interface MapBaseProps {
193
198
  zoom?: number;
@@ -69,18 +69,6 @@ unpredictable css rules order in build */
69
69
  }
70
70
  .pc-header__buttons-item {
71
71
  position: relative;
72
- height: var(--header-height);
73
- line-height: var(--header-height);
74
- cursor: pointer;
75
- outline: none;
76
- color: inherit;
77
- text-decoration: none;
78
- }
79
- .utilityfocus .pc-header__buttons-item:focus {
80
- outline: 2px solid #ffdb4d;
81
- }
82
- .pc-header__buttons-item:hover, .pc-header__buttons-item:active {
83
- color: var(--yc-color-text-link);
84
72
  }
85
73
  .pc-header__buttons-item:not(:last-child) {
86
74
  margin-right: 20px;
@@ -14,18 +14,6 @@ unpredictable css rules order in build */
14
14
  }
15
15
  .pc-navigation__links-item {
16
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 .pc-navigation__links-item:focus {
25
- outline: 2px solid #ffdb4d;
26
- }
27
- .pc-navigation__links-item:hover, .pc-navigation__links-item:active {
28
- color: var(--yc-color-text-link);
29
17
  }
30
18
  .pc-navigation__links-item:not(:last-child) {
31
19
  margin-right: 20px;
@@ -1,5 +1,4 @@
1
- import React, { useCallback, useContext, useEffect, useRef, useState } from 'react';
2
- import _ from 'lodash';
1
+ import React, { useCallback, useContext, useEffect } from 'react';
3
2
  import OverflowScroller from '../../../components/OverflowScroller/OverflowScroller';
4
3
  import { LocationContext } from '../../../context/locationContext';
5
4
  import { block } from '../../../utils';
@@ -7,44 +6,16 @@ import { ItemColumnName } from '../../constants';
7
6
  import { NavigationListItem } from '../NavigationListItem/NavigationListItem';
8
7
  import './Navigation.css';
9
8
  const b = block('navigation');
10
- const EVENT_HANDLE_DELAY = 100;
11
- const Navigation = ({ className, onActiveItemChange, links, activeItemId, highlightActiveItem, }) => {
9
+ const Navigation = ({ className, onActiveItemChange, links, activeItemId, }) => {
12
10
  const { asPath, pathname } = useContext(LocationContext);
13
- const itemRefs = useRef([]);
14
- const [itemPositions, setItemPosition] = useState([]);
15
- const [lastLeftScroll, setLastLeftScroll] = useState(0);
16
11
  const hidePopup = useCallback(() => {
17
12
  onActiveItemChange();
18
13
  }, [onActiveItemChange]);
19
- const calculateItemPositions = useCallback(() => {
20
- if (itemRefs.current.length) {
21
- const currentItemPositions = itemRefs.current.map((itemRef) => (itemRef && itemRef.getBoundingClientRect().left) || 0);
22
- setItemPosition(currentItemPositions);
23
- }
24
- }, []);
25
- useEffect(() => {
26
- const debouncedCalculateItemPositions = _.debounce(calculateItemPositions, EVENT_HANDLE_DELAY);
27
- const debouncedCalculateOnScroll = _.debounce(() => {
28
- const curLeftScroll = window.pageXOffset;
29
- if (curLeftScroll !== lastLeftScroll) {
30
- setLastLeftScroll(window.pageXOffset);
31
- calculateItemPositions();
32
- }
33
- }, EVENT_HANDLE_DELAY);
34
- calculateItemPositions();
35
- setLastLeftScroll(window.pageXOffset);
36
- window.addEventListener('resize', debouncedCalculateItemPositions);
37
- window.addEventListener('scroll', debouncedCalculateOnScroll);
38
- return () => {
39
- window.removeEventListener(`resize`, debouncedCalculateItemPositions);
40
- window.removeEventListener('scroll', debouncedCalculateOnScroll);
41
- };
42
- }, [calculateItemPositions, itemRefs, lastLeftScroll]);
43
14
  useEffect(() => {
44
15
  hidePopup();
45
16
  }, [hidePopup, asPath, pathname]);
46
- return (React.createElement(OverflowScroller, { className: b(null, className), onScrollStart: hidePopup, onScrollEnd: calculateItemPositions },
17
+ return (React.createElement(OverflowScroller, { className: b(null, className), onScrollStart: hidePopup },
47
18
  React.createElement("nav", null,
48
- React.createElement("ul", { className: b('links') }, links.map((link, index) => (React.createElement(NavigationListItem, { key: index, className: b('links-item'), item: link, itemRefs: itemRefs, index: index, activeItemId: activeItemId, highlightActiveItem: highlightActiveItem, hidePopup: hidePopup, itemPositions: itemPositions, column: ItemColumnName.Left, onActiveItemChange: onActiveItemChange })))))));
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 })))))));
49
20
  };
50
21
  export default Navigation;
@@ -1,10 +1,10 @@
1
1
  import React, { MouseEventHandler } from 'react';
2
2
  import { NavigationDropdownItem } from '../../../models';
3
3
  export interface NavigationDropdownProps {
4
+ className?: string;
4
5
  data: NavigationDropdownItem;
5
6
  onClick: MouseEventHandler;
6
7
  isActive: boolean;
7
- position: number;
8
8
  hidePopup: () => void;
9
9
  }
10
10
  declare const NavigationDropdown: React.FC<NavigationDropdownProps>;
@@ -1,12 +1,13 @@
1
1
  import { __rest } from "tslib";
2
- import React, { Fragment } from 'react';
2
+ import React, { Fragment, useRef } from 'react';
3
3
  import { NavigationItemType } from '../../../models';
4
4
  import NavigationItem from '../NavigationItem/NavigationItem';
5
5
  import NavigationPopup from '../NavigationPopup/NavigationPopup';
6
- const NavigationDropdown = ({ data, isActive, position, hidePopup, onClick, }) => {
6
+ const NavigationDropdown = ({ className, data, isActive, hidePopup, onClick, }) => {
7
+ const anchorRef = useRef(null);
7
8
  const { text, icon, items } = data, popupProps = __rest(data, ["text", "icon", "items"]);
8
9
  return (React.createElement(Fragment, null,
9
- React.createElement(NavigationItem, { onClick: onClick, isOpened: isActive, data: { text, type: NavigationItemType.Dropdown, icon } }),
10
- isActive && (React.createElement(NavigationPopup, Object.assign({ left: position, onClose: hidePopup, items: items }, popupProps)))));
10
+ React.createElement(NavigationItem, { className: className, ref: anchorRef, onClick: onClick, isOpened: isActive, data: { text, type: NavigationItemType.Dropdown, icon } }),
11
+ React.createElement(NavigationPopup, Object.assign({ open: isActive, onClose: hidePopup, items: items, anchorRef: anchorRef }, popupProps))));
11
12
  };
12
13
  export default NavigationDropdown;
@@ -6,5 +6,5 @@ export interface NavigationItemProps {
6
6
  onClick?: MouseEventHandler;
7
7
  isOpened?: boolean;
8
8
  }
9
- declare const NavigationItem: React.FC<NavigationItemProps>;
9
+ declare const NavigationItem: React.ForwardRefExoticComponent<NavigationItemProps & React.RefAttributes<HTMLElement>>;
10
10
  export default NavigationItem;
@@ -17,12 +17,13 @@ const NavigationItemsMap = {
17
17
  [NavigationItemType.Link]: NavigationLink,
18
18
  [NavigationItemType.GithubButton]: GithubButton,
19
19
  };
20
- const NavigationItem = (_a) => {
20
+ const NavigationItem = React.forwardRef((_a, ref) => {
21
21
  var { data, className } = _a, props = __rest(_a, ["data", "className"]);
22
22
  const { type = NavigationItemType.Link } = data;
23
23
  const Component = NavigationItemsMap[type];
24
- const componentProps = useMemo(() => (Object.assign(Object.assign({ className }, data), props)), [className, data, props]);
24
+ const componentProps = useMemo(() => (Object.assign(Object.assign(Object.assign({ className }, data), props), { ref })), [className, data, props, ref]);
25
25
  return (React.createElement(BlockIdContext.Provider, { value: ANALYTICS_ID },
26
26
  React.createElement(Component, Object.assign({}, componentProps))));
27
- };
27
+ });
28
+ NavigationItem.displayName = 'NavigationItem';
28
29
  export default NavigationItem;
@@ -2,6 +2,4 @@ import React from 'react';
2
2
  import { DropdownItemData } from '../../../../../models';
3
3
  import { NavigationItemProps } from '../../NavigationItem';
4
4
  import './NavigationDropdown.css';
5
- type NavigationDropdownProps = NavigationItemProps & DropdownItemData;
6
- export declare const NavigationDropdown: React.FC<NavigationDropdownProps>;
7
- export {};
5
+ export declare const NavigationDropdown: React.ForwardRefExoticComponent<NavigationItemProps & DropdownItemData & React.RefAttributes<HTMLElement>>;
@@ -7,10 +7,11 @@ import { ContentWrapper } from '../ContentWrapper/ContentWrapper';
7
7
  import './NavigationDropdown.css';
8
8
  const b = block('navigation-dropdown');
9
9
  const TOGGLE_ARROW_SIZE = 12;
10
- export const NavigationDropdown = (_a) => {
10
+ export const NavigationDropdown = React.forwardRef((_a, ref) => {
11
11
  var { text, icon, isOpened, className } = _a, props = __rest(_a, ["text", "icon", "isOpened", "className"]);
12
12
  const iconData = icon && getMediaImage(icon);
13
- return (React.createElement("span", Object.assign({}, props, { className: b(null, className) }),
13
+ return (React.createElement("span", Object.assign({ ref: ref }, props, { className: b(null, className) }),
14
14
  React.createElement(ContentWrapper, { text: text, icon: iconData }),
15
15
  React.createElement(ToggleArrow, { className: b('arrow'), size: TOGGLE_ARROW_SIZE, type: 'vertical', iconType: "navigation", open: isOpened })));
16
- };
16
+ });
17
+ NavigationDropdown.displayName = 'NavigationDropdown';
@@ -1,3 +1,19 @@
1
+ /* use this for style redefinitions to awoid problems with
2
+ unpredictable css rules order in build */
3
+ .pc-navigation-list-item {
4
+ height: var(--header-height);
5
+ line-height: var(--header-height);
6
+ cursor: pointer;
7
+ outline: none;
8
+ color: inherit;
9
+ text-decoration: none;
10
+ }
11
+ .utilityfocus .pc-navigation-list-item:focus {
12
+ outline: 2px solid #ffdb4d;
13
+ }
14
+ .pc-navigation-list-item__content:hover, .pc-navigation-list-item__content:active {
15
+ color: var(--yc-color-text-link);
16
+ }
1
17
  .pc-navigation-list-item__slider-container {
2
18
  position: absolute;
3
19
  right: 0;
@@ -1,4 +1,3 @@
1
- import React from 'react';
2
1
  import { ClassNameProps, NavigationItemModel } from '../../../models';
3
2
  import { ItemColumnName } from '../../constants';
4
3
  import './NavigationListItem.css';
@@ -7,11 +6,9 @@ type NavigationListItemProps = {
7
6
  index: number;
8
7
  column: ItemColumnName;
9
8
  activeItemId?: string;
10
- itemPositions?: number[];
11
- itemRefs?: React.MutableRefObject<(HTMLLIElement | null)[]>;
12
9
  highlightActiveItem?: boolean;
13
10
  hidePopup: () => void;
14
11
  onActiveItemChange: (id?: string) => void;
15
12
  } & ClassNameProps;
16
- export declare const NavigationListItem: ({ item, itemRefs, className, index, activeItemId, highlightActiveItem, hidePopup, itemPositions, column, onActiveItemChange, }: NavigationListItemProps) => JSX.Element;
13
+ export declare const NavigationListItem: ({ item, className, index, activeItemId, highlightActiveItem, hidePopup, column, onActiveItemChange, }: NavigationListItemProps) => JSX.Element;
17
14
  export {};
@@ -1,14 +1,12 @@
1
- import React, { useRef } from 'react';
1
+ import React from 'react';
2
2
  import { NavigationItemType } from '../../../models';
3
3
  import { block } from '../../../utils';
4
4
  import { getItemClickHandler } from '../../utils';
5
5
  import NavigationDropdownItem from '../NavigationDropdownItem/NavigationDropdownItem';
6
6
  import NavigationItem from '../NavigationItem/NavigationItem';
7
7
  import './NavigationListItem.css';
8
- const b = block('navigation');
9
- export const NavigationListItem = ({ item, itemRefs, className, index, activeItemId, highlightActiveItem, hidePopup, itemPositions, column, onActiveItemChange, }) => {
10
- var _a;
11
- const ref = useRef(null);
8
+ const b = block('navigation-list-item');
9
+ export const NavigationListItem = ({ item, className, index, activeItemId, highlightActiveItem, hidePopup, column, onActiveItemChange, }) => {
12
10
  const id = `${column}-${index}`;
13
11
  const isActive = id === activeItemId;
14
12
  const onClick = getItemClickHandler({
@@ -17,8 +15,8 @@ export const NavigationListItem = ({ item, itemRefs, className, index, activeIte
17
15
  activeItemId,
18
16
  onActiveItemChange,
19
17
  });
20
- return (React.createElement("li", { ref: itemRefs ? (el) => itemRefs.current.push(el) : ref, className: className },
21
- item.type === NavigationItemType.Dropdown ? (React.createElement(NavigationDropdownItem, { data: item, onClick: onClick, isActive: isActive, position: (itemPositions === null || itemPositions === void 0 ? void 0 : itemPositions[index]) || ((_a = ref.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().left) || 0, hidePopup: hidePopup })) : (React.createElement(NavigationItem, { data: item, onClick: onClick })),
18
+ return (React.createElement("li", { className: b(null, className) },
19
+ item.type === NavigationItemType.Dropdown ? (React.createElement(NavigationDropdownItem, { className: b('content'), data: item, onClick: onClick, isActive: isActive, hidePopup: hidePopup })) : (React.createElement(NavigationItem, { className: b('content'), data: item, onClick: onClick })),
22
20
  highlightActiveItem && isActive && (React.createElement("div", { className: b('slider-container') },
23
21
  React.createElement("div", { className: b('slider') })))));
24
22
  };
@@ -1,11 +1,8 @@
1
1
  /* use this for style redefinitions to awoid problems with
2
2
  unpredictable css rules order in build */
3
3
  .pc-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));
4
+ margin-left: -16px;
5
+ margin-top: -16px;
9
6
  z-index: 101;
10
7
  display: flex;
11
8
  flex-direction: column;
@@ -2,10 +2,11 @@ import React from 'react';
2
2
  import { NavigationLinkItem } from '../../../models';
3
3
  import './NavigationPopup.css';
4
4
  export interface NavigationPopupProps {
5
+ open: boolean;
5
6
  items: NavigationLinkItem[];
6
7
  onClose: () => void;
7
- left?: number;
8
8
  className?: string;
9
+ anchorRef: React.RefObject<Element>;
9
10
  }
10
11
  export declare const NavigationPopup: React.FC<NavigationPopupProps>;
11
12
  export default NavigationPopup;
@@ -1,41 +1,15 @@
1
- import React, { useCallback, useEffect, useRef, useState } from 'react';
2
- import _ from 'lodash';
3
- import { Portal } from '@gravity-ui/uikit';
4
- import { OutsideClick } from '../../../components';
1
+ import React from 'react';
2
+ import { Popup } from '@gravity-ui/uikit';
5
3
  import { block } from '../../../utils';
6
4
  import NavigationItem from '../NavigationItem/NavigationItem';
7
5
  import './NavigationPopup.css';
8
6
  const b = block('navigation-popup');
9
- export const NavigationPopup = ({ items, left, onClose }) => {
10
- const [calculatedLeft, setCalculatedLeft] = useState(left);
11
- const popupRef = useRef(null);
12
- const calculateLeft = useCallback(() => {
13
- if (popupRef && popupRef.current && left) {
14
- const right = left + popupRef.current.offsetWidth;
15
- const docWidth = document.body.clientWidth;
16
- const currentLeft = right > docWidth ? left - (right - docWidth) : left;
17
- setCalculatedLeft(currentLeft);
18
- }
19
- else {
20
- setCalculatedLeft(left);
21
- }
22
- }, [left]);
23
- useEffect(() => {
24
- const debounceCalculateLeft = _.debounce(calculateLeft, 100);
25
- calculateLeft();
26
- window.addEventListener('resize', debounceCalculateLeft);
27
- return () => {
28
- window.removeEventListener('resize', debounceCalculateLeft);
29
- };
30
- }, [calculateLeft]);
31
- useEffect(() => {
32
- calculateLeft();
33
- }, [calculateLeft, left]);
34
- if (!document || !document.body) {
35
- return null;
36
- }
37
- return (React.createElement(Portal, null,
38
- React.createElement("div", { ref: popupRef, className: b(), style: { left: calculatedLeft } },
39
- React.createElement(OutsideClick, { onOutsideClick: onClose }, items.map((item) => (React.createElement(NavigationItem, { key: item.text, className: b('link'), data: item })))))));
7
+ const OFFSET_RESET = [0, 0];
8
+ export const NavigationPopup = ({ anchorRef, items, onClose, className, open, }) => {
9
+ return (React.createElement(Popup
10
+ // Workaround to recalculate position on every opening. Required for valid position calculation for scrolled header links.
11
+ , {
12
+ // Workaround to recalculate position on every opening. Required for valid position calculation for scrolled header links.
13
+ anchorRef: open ? anchorRef : undefined, className: b(null, className), open: open, onClose: onClose, onOutsideClick: onClose, keepMounted: true, disablePortal: true, strategy: "fixed", placement: "bottom-start", offset: OFFSET_RESET }, items.map((item) => (React.createElement(NavigationItem, { key: item.text, className: b('link'), data: item })))));
40
14
  };
41
15
  export default NavigationPopup;
@@ -209,6 +209,9 @@ export declare function generateDefaultSchema(config?: SchemaCustomConfig): {
209
209
  parallax: {
210
210
  type: string;
211
211
  };
212
+ fullWidthMedia: {
213
+ type: string;
214
+ };
212
215
  animated: {
213
216
  type: string;
214
217
  };
@@ -286,6 +286,9 @@ export declare const BackgroundProps: {
286
286
  parallax: {
287
287
  type: string;
288
288
  };
289
+ fullWidthMedia: {
290
+ type: string;
291
+ };
289
292
  animated: {
290
293
  type: string;
291
294
  };
@@ -153,6 +153,8 @@ export const BackgroundProps = {
153
153
  enum: ['contain', 'cover'],
154
154
  }, parallax: {
155
155
  type: 'boolean',
156
+ }, fullWidthMedia: {
157
+ type: 'boolean',
156
158
  } }),
157
159
  };
158
160
  export const LinkProps = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/page-constructor",
3
- "version": "2.6.0",
3
+ "version": "2.8.0",
4
4
  "description": "Gravity UI Page Constructor",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -188,6 +188,11 @@ export interface MediaComponentDataLensProps {
188
188
  export interface MediaProps extends Animatable, Partial<MediaComponentDataLensProps>, Partial<MediaComponentYoutubeProps>, Partial<MediaComponentImageProps>, Partial<MediaComponentVideoProps> {
189
189
  color?: string;
190
190
  }
191
+ export interface BackgroundMediaProps extends MediaProps, Animatable {
192
+ fullWidthMedia?: boolean;
193
+ className?: string;
194
+ mediaClassName?: string;
195
+ }
191
196
  export type Coordinate = number[];
192
197
  export interface MapBaseProps {
193
198
  zoom?: number;
@@ -472,17 +472,6 @@ unpredictable css rules order in build */
472
472
  }
473
473
  }
474
474
 
475
- @mixin navigation-link() {
476
- cursor: pointer;
477
- @include islands-focus();
478
- @include reset-link-style();
479
-
480
- &:hover,
481
- &:active {
482
- color: var(--yc-color-text-link);
483
- }
484
- }
485
-
486
475
  @mixin button($color, $backgroundColor, $hoverColor: $color, $hoverBackgroundColor) {
487
476
  --yc-button-background-color: #{$backgroundColor};
488
477
  --yc-button-background-color-hover: #{$hoverBackgroundColor};