@gravity-ui/page-constructor 1.7.0-alpha.2 → 1.7.0-alpha.4

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 (24) hide show
  1. package/build/cjs/components/navigation/components/Header/Header.d.ts +1 -1
  2. package/build/cjs/components/navigation/components/Logo/Logo.css +0 -1
  3. package/build/cjs/components/navigation/components/Logo/Logo.js +1 -1
  4. package/build/cjs/components/navigation/components/NavigationItem/NavigationItem.css +1 -0
  5. package/build/cjs/components/navigation/components/NavigationItem/NavigationItem.d.ts +2 -1
  6. package/build/cjs/components/navigation/components/NavigationItem/NavigationItem.js +16 -10
  7. package/build/cjs/components/navigation/components/NavigationPopup/NavigationPopup-class.d.ts +24 -0
  8. package/build/cjs/components/navigation/components/NavigationPopup/NavigationPopup-class.js +57 -0
  9. package/build/cjs/components/navigation/components/NavigationPopup/NavigationPopup.d.ts +4 -18
  10. package/build/cjs/components/navigation/components/NavigationPopup/NavigationPopup.js +35 -44
  11. package/build/cjs/models/navigation.d.ts +1 -0
  12. package/build/esm/components/navigation/components/Header/Header.d.ts +1 -1
  13. package/build/esm/components/navigation/components/Logo/Logo.css +0 -1
  14. package/build/esm/components/navigation/components/Logo/Logo.js +1 -1
  15. package/build/esm/components/navigation/components/NavigationItem/NavigationItem.css +1 -0
  16. package/build/esm/components/navigation/components/NavigationItem/NavigationItem.d.ts +2 -1
  17. package/build/esm/components/navigation/components/NavigationItem/NavigationItem.js +13 -7
  18. package/build/esm/components/navigation/components/NavigationPopup/NavigationPopup-class.d.ts +25 -0
  19. package/build/esm/components/navigation/components/NavigationPopup/NavigationPopup-class.js +54 -0
  20. package/build/esm/components/navigation/components/NavigationPopup/NavigationPopup.d.ts +4 -18
  21. package/build/esm/components/navigation/components/NavigationPopup/NavigationPopup.js +34 -44
  22. package/build/esm/models/navigation.d.ts +1 -0
  23. package/package.json +1 -1
  24. package/server/models/navigation.d.ts +1 -0
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { HeaderData, NavigationLogo } from '../../../../models/navigation';
2
+ import { HeaderData, NavigationLogo } from '../../../../models';
3
3
  export interface HeaderProps {
4
4
  logo: NavigationLogo;
5
5
  data: HeaderData;
@@ -15,7 +15,6 @@ unpredictable css rules order in build */
15
15
  }
16
16
  .logo__icon {
17
17
  display: flex;
18
- height: 36px;
19
18
  margin-right: 8px;
20
19
  object-fit: contain;
21
20
  }
@@ -11,7 +11,7 @@ const Logo = ({ icon, text, className }) => {
11
11
  const imageData = (0, utils_1.getMediaImage)(icon);
12
12
  return (react_1.default.createElement(RouterLink_1.default, { href: "/", passHref: true },
13
13
  react_1.default.createElement("div", { className: b(null, className) },
14
- imageData && react_1.default.createElement(index_1.Image, Object.assign({}, imageData)),
14
+ imageData && react_1.default.createElement(index_1.Image, Object.assign({ className: b('icon') }, imageData)),
15
15
  react_1.default.createElement("span", { className: b('text') }, text))));
16
16
  };
17
17
  exports.default = Logo;
@@ -28,6 +28,7 @@ unpredictable css rules order in build */
28
28
  margin-left: 5px;
29
29
  }
30
30
  .navigation-item__icon {
31
+ display: flex;
31
32
  width: 20px;
32
33
  height: 20px;
33
34
  margin-right: 8px;
@@ -1,5 +1,5 @@
1
1
  import React, { MouseEventHandler } from 'react';
2
- import { NavigationButtonItem, NavigationDropdownItem, NavigationSocialItem, NavigationLinkItem } from '../../../../models/navigation';
2
+ import { NavigationButtonItem, NavigationDropdownItem, NavigationSocialItem, NavigationLinkItem } from '../../../../models';
3
3
  declare type DropdownItemData = Omit<NavigationDropdownItem, 'items'>;
4
4
  export declare type NavigationItemData = NavigationLinkItem | NavigationButtonItem | NavigationSocialItem | DropdownItemData;
5
5
  export interface NavigationItemProps {
@@ -7,6 +7,7 @@ export interface NavigationItemProps {
7
7
  className?: string;
8
8
  onClick?: MouseEventHandler;
9
9
  isOpened?: boolean;
10
+ hostname?: string;
10
11
  }
11
12
  declare const NavigationItem: React.FC<NavigationItemProps>;
12
13
  export default NavigationItem;
@@ -6,13 +6,13 @@ const bem_cn_lite_1 = (0, tslib_1.__importDefault)(require("bem-cn-lite"));
6
6
  const index_1 = require("../../../index");
7
7
  const utils_1 = require("../../../../utils");
8
8
  const locationContext_1 = require("../../../../context/locationContext");
9
- const navigation_1 = require("../../../../models/navigation");
9
+ const models_1 = require("../../../../models");
10
10
  const icons_1 = require("../../../../icons");
11
11
  const SocialIcon_1 = (0, tslib_1.__importDefault)(require("../SocialIcon/SocialIcon"));
12
12
  const utils_2 = require("../../../Media/Image/utils");
13
13
  const b = (0, bem_cn_lite_1.default)('navigation-item');
14
14
  const Content = ({ text, icon }) => (react_1.default.createElement(react_1.Fragment, null,
15
- icon && react_1.default.createElement("img", Object.assign({ className: b('icon') }, icon)),
15
+ icon && react_1.default.createElement(index_1.Image, Object.assign({ className: b('icon') }, icon)),
16
16
  react_1.default.createElement("span", { className: b('text') }, text)));
17
17
  const NavigationDropdown = (_a) => {
18
18
  var { text, icon, isOpened } = _a, props = (0, tslib_1.__rest)(_a, ["text", "icon", "isOpened"]);
@@ -22,9 +22,10 @@ const NavigationDropdown = (_a) => {
22
22
  react_1.default.createElement(index_1.ToggleArrow, { className: b('dropdown'), size: 12, type: 'vertical', iconType: "navigation", open: isOpened })));
23
23
  };
24
24
  const NavigationLink = (props) => {
25
- const { hostname } = (0, react_1.useContext)(locationContext_1.LocationContext);
26
- const { url, text, icon, arrow, target } = props, rest = (0, tslib_1.__rest)(props, ["url", "text", "icon", "arrow", "target"]);
27
- const linkExtraProps = (0, utils_1.getLinkProps)(url, hostname, target);
25
+ const { hostname: locationHostname } = (0, react_1.useContext)(locationContext_1.LocationContext);
26
+ const { url, text, icon, arrow, target, hostname } = props, rest = (0, tslib_1.__rest)(props, ["url", "text", "icon", "arrow", "target", "hostname"]);
27
+ const currentHostname = locationHostname || hostname;
28
+ const linkExtraProps = (0, utils_1.getLinkProps)(url, currentHostname, target);
28
29
  const iconData = icon && (0, utils_2.getMediaImage)(icon);
29
30
  const content = (react_1.default.createElement(react_1.Fragment, null,
30
31
  react_1.default.createElement(Content, { text: text, icon: iconData }),
@@ -32,17 +33,22 @@ const NavigationLink = (props) => {
32
33
  return (linkExtraProps === null || linkExtraProps === void 0 ? void 0 : linkExtraProps.target) ? (react_1.default.createElement("a", Object.assign({ href: url, title: text }, rest, linkExtraProps), content)) : (react_1.default.createElement(index_1.RouterLink, { href: url, passHref: true },
33
34
  react_1.default.createElement("a", Object.assign({}, rest), content)));
34
35
  };
36
+ const NavigationButton = (props) => {
37
+ const { url, target } = props;
38
+ return target ? (react_1.default.createElement(index_1.Button, Object.assign({}, props, { url: url }))) : (react_1.default.createElement(index_1.RouterLink, { href: url },
39
+ react_1.default.createElement(index_1.Button, Object.assign({}, props, { url: url }))));
40
+ };
35
41
  //todo: add types support form component in map
36
42
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
37
43
  const NavigationItemsMap = {
38
- [navigation_1.NavigationItemType.Button]: index_1.RouterLink,
39
- [navigation_1.NavigationItemType.Social]: SocialIcon_1.default,
40
- [navigation_1.NavigationItemType.Dropdown]: NavigationDropdown,
41
- [navigation_1.NavigationItemType.Link]: NavigationLink,
44
+ [models_1.NavigationItemType.Button]: NavigationButton,
45
+ [models_1.NavigationItemType.Social]: SocialIcon_1.default,
46
+ [models_1.NavigationItemType.Dropdown]: NavigationDropdown,
47
+ [models_1.NavigationItemType.Link]: NavigationLink,
42
48
  };
43
49
  const NavigationItem = (_a) => {
44
50
  var { data, className } = _a, props = (0, tslib_1.__rest)(_a, ["data", "className"]);
45
- const { type = navigation_1.NavigationItemType.Link } = data;
51
+ const { type = models_1.NavigationItemType.Link } = data;
46
52
  const Component = NavigationItemsMap[type];
47
53
  const componentProps = (0, react_1.useMemo)(() => (Object.assign(Object.assign({ className: b({ type }, className) }, data), props)), [className, data, props, type]);
48
54
  return react_1.default.createElement(Component, Object.assign({}, componentProps));
@@ -0,0 +1,24 @@
1
+ import React, { RefObject } from 'react';
2
+ import { NavigationLinkItem } from '../../../../models/navigation';
3
+ export interface NavigationPopupProps {
4
+ items: NavigationLinkItem[];
5
+ onClose: () => void;
6
+ left?: number;
7
+ className?: string;
8
+ }
9
+ interface NavigationPopupState {
10
+ calculatedLeft?: number;
11
+ }
12
+ export default class NavigationPopup extends React.Component<NavigationPopupProps, NavigationPopupState> {
13
+ ref: RefObject<HTMLDivElement>;
14
+ state: {
15
+ calculatedLeft: number | undefined;
16
+ };
17
+ private calculateLeft;
18
+ componentDidMount(): void;
19
+ componentDidUpdate(prevProps: NavigationPopupProps): void;
20
+ componentWillUnmount(): void;
21
+ render(): JSX.Element | null;
22
+ private renderDefaultPopup;
23
+ }
24
+ export {};
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const lodash_1 = (0, tslib_1.__importDefault)(require("lodash"));
5
+ const bem_cn_lite_1 = (0, tslib_1.__importDefault)(require("bem-cn-lite"));
6
+ const react_1 = (0, tslib_1.__importStar)(require("react"));
7
+ const uikit_1 = require("@gravity-ui/uikit");
8
+ const index_1 = require("../../../index");
9
+ const NavigationItem_1 = (0, tslib_1.__importDefault)(require("../NavigationItem/NavigationItem"));
10
+ const b = (0, bem_cn_lite_1.default)('navigation-popup');
11
+ class NavigationPopup extends react_1.default.Component {
12
+ constructor() {
13
+ super(...arguments);
14
+ this.ref = (0, react_1.createRef)();
15
+ this.state = {
16
+ calculatedLeft: this.props.left,
17
+ };
18
+ this.calculateLeft = lodash_1.default.debounce(() => {
19
+ const { left } = this.props;
20
+ if (this.ref && this.ref.current && left) {
21
+ const right = left + this.ref.current.offsetWidth;
22
+ const docWidth = document.body.clientWidth;
23
+ const calculatedLeft = right > docWidth ? left - (right - docWidth) : left;
24
+ this.setState({ calculatedLeft });
25
+ }
26
+ else {
27
+ this.setState({ calculatedLeft: left });
28
+ }
29
+ }, 100);
30
+ }
31
+ componentDidMount() {
32
+ this.calculateLeft();
33
+ window.addEventListener('resize', this.calculateLeft);
34
+ }
35
+ componentDidUpdate(prevProps) {
36
+ if (prevProps.left !== this.props.left) {
37
+ this.calculateLeft();
38
+ }
39
+ }
40
+ componentWillUnmount() {
41
+ window.removeEventListener('resize', this.calculateLeft);
42
+ }
43
+ render() {
44
+ if (!document || !document.body) {
45
+ return null;
46
+ }
47
+ const { onClose } = this.props;
48
+ const { calculatedLeft } = this.state;
49
+ return (react_1.default.createElement(uikit_1.Portal, null,
50
+ react_1.default.createElement("div", { ref: this.ref, className: b(), style: { left: calculatedLeft } },
51
+ react_1.default.createElement(index_1.OutsideClick, { onOutsideClick: onClose }, this.renderDefaultPopup()))));
52
+ }
53
+ renderDefaultPopup() {
54
+ return (react_1.default.createElement(react_1.Fragment, null, this.props.items.map((item) => (react_1.default.createElement(NavigationItem_1.default, { key: item.text, className: b('link'), data: item })))));
55
+ }
56
+ }
57
+ exports.default = NavigationPopup;
@@ -1,24 +1,10 @@
1
- import React, { RefObject } from 'react';
2
- import { NavigationLinkItem } from '../../../../models/navigation';
1
+ import React from 'react';
2
+ import { NavigationLinkItem } from '../../../../models';
3
3
  export interface NavigationPopupProps {
4
4
  items: NavigationLinkItem[];
5
5
  onClose: () => void;
6
6
  left?: number;
7
7
  className?: string;
8
8
  }
9
- interface NavigationPopupState {
10
- calculatedLeft?: number;
11
- }
12
- export default class NavigationPopup extends React.Component<NavigationPopupProps, NavigationPopupState> {
13
- ref: RefObject<HTMLDivElement>;
14
- state: {
15
- calculatedLeft: number | undefined;
16
- };
17
- private calculateLeft;
18
- componentDidMount(): void;
19
- componentDidUpdate(prevProps: NavigationPopupProps): void;
20
- componentWillUnmount(): void;
21
- render(): JSX.Element | null;
22
- private renderDefaultPopup;
23
- }
24
- export {};
9
+ export declare const NavigationPopup: React.FC<NavigationPopupProps>;
10
+ export default NavigationPopup;
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NavigationPopup = void 0;
3
4
  const tslib_1 = require("tslib");
4
5
  const lodash_1 = (0, tslib_1.__importDefault)(require("lodash"));
5
6
  const bem_cn_lite_1 = (0, tslib_1.__importDefault)(require("bem-cn-lite"));
@@ -7,51 +8,41 @@ const react_1 = (0, tslib_1.__importStar)(require("react"));
7
8
  const uikit_1 = require("@gravity-ui/uikit");
8
9
  const index_1 = require("../../../index");
9
10
  const NavigationItem_1 = (0, tslib_1.__importDefault)(require("../NavigationItem/NavigationItem"));
11
+ const locationContext_1 = require("../../../../context/locationContext");
10
12
  const b = (0, bem_cn_lite_1.default)('navigation-popup');
11
- class NavigationPopup extends react_1.default.Component {
12
- constructor() {
13
- super(...arguments);
14
- this.ref = (0, react_1.createRef)();
15
- this.state = {
16
- calculatedLeft: this.props.left,
17
- };
18
- this.calculateLeft = lodash_1.default.debounce(() => {
19
- const { left } = this.props;
20
- if (this.ref && this.ref.current && left) {
21
- const right = left + this.ref.current.offsetWidth;
22
- const docWidth = document.body.clientWidth;
23
- const calculatedLeft = right > docWidth ? left - (right - docWidth) : left;
24
- this.setState({ calculatedLeft });
25
- }
26
- else {
27
- this.setState({ calculatedLeft: left });
28
- }
29
- }, 100);
30
- }
31
- componentDidMount() {
32
- this.calculateLeft();
33
- window.addEventListener('resize', this.calculateLeft);
34
- }
35
- componentDidUpdate(prevProps) {
36
- if (prevProps.left !== this.props.left) {
37
- this.calculateLeft();
13
+ const NavigationPopup = ({ items, left, onClose }) => {
14
+ const [calculatedLeft, setCalculatedLeft] = (0, react_1.useState)(left);
15
+ const popupRef = (0, react_1.useRef)(null);
16
+ const { hostname } = (0, react_1.useContext)(locationContext_1.LocationContext);
17
+ const calculateLeft = (0, react_1.useCallback)(() => {
18
+ if (popupRef && popupRef.current && left) {
19
+ const right = left + popupRef.current.offsetWidth;
20
+ const docWidth = document.body.clientWidth;
21
+ const currentLeft = right > docWidth ? left - (right - docWidth) : left;
22
+ setCalculatedLeft(currentLeft);
38
23
  }
39
- }
40
- componentWillUnmount() {
41
- window.removeEventListener('resize', this.calculateLeft);
42
- }
43
- render() {
44
- if (!document || !document.body) {
45
- return null;
24
+ else {
25
+ setCalculatedLeft(left);
46
26
  }
47
- const { onClose } = this.props;
48
- const { calculatedLeft } = this.state;
49
- return (react_1.default.createElement(uikit_1.Portal, null,
50
- react_1.default.createElement("div", { ref: this.ref, className: b(), style: { left: calculatedLeft } },
51
- react_1.default.createElement(index_1.OutsideClick, { onOutsideClick: onClose }, this.renderDefaultPopup()))));
52
- }
53
- renderDefaultPopup() {
54
- return (react_1.default.createElement(react_1.Fragment, null, this.props.items.map((item) => (react_1.default.createElement(NavigationItem_1.default, { key: item.text, className: b('link'), data: item })))));
27
+ }, [left]);
28
+ (0, react_1.useEffect)(() => {
29
+ const debounceCalculateLeft = lodash_1.default.debounce(calculateLeft, 100);
30
+ calculateLeft();
31
+ window.addEventListener('resize', debounceCalculateLeft);
32
+ return () => {
33
+ window.removeEventListener('resize', debounceCalculateLeft);
34
+ };
35
+ }, [calculateLeft]);
36
+ (0, react_1.useEffect)(() => {
37
+ calculateLeft();
38
+ }, [calculateLeft, left]);
39
+ if (!document || !document.body) {
40
+ return null;
55
41
  }
56
- }
57
- exports.default = NavigationPopup;
42
+ const renderDefaultPopup = (react_1.default.createElement(react_1.Fragment, null, items.map((item) => (react_1.default.createElement(NavigationItem_1.default, { key: item.text, className: b('link'), data: item, hostname: hostname })))));
43
+ return (react_1.default.createElement(uikit_1.Portal, null,
44
+ react_1.default.createElement("div", { ref: popupRef, className: b(), style: { left: calculatedLeft } },
45
+ react_1.default.createElement(index_1.OutsideClick, { onOutsideClick: onClose }, renderDefaultPopup))));
46
+ };
47
+ exports.NavigationPopup = NavigationPopup;
48
+ exports.default = exports.NavigationPopup;
@@ -15,6 +15,7 @@ export interface NavigationLinkItem extends NavigationItemBase {
15
15
  url: string;
16
16
  arrow?: boolean;
17
17
  target?: string;
18
+ hostname?: string;
18
19
  }
19
20
  export interface NavigationButtonItem extends ButtonProps {
20
21
  type: NavigationItemType.Button;
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { HeaderData, NavigationLogo } from '../../../../models/navigation';
2
+ import { HeaderData, NavigationLogo } from '../../../../models';
3
3
  import './Header.css';
4
4
  export interface HeaderProps {
5
5
  logo: NavigationLogo;
@@ -15,7 +15,6 @@ unpredictable css rules order in build */
15
15
  }
16
16
  .logo__icon {
17
17
  display: flex;
18
- height: 36px;
19
18
  margin-right: 8px;
20
19
  object-fit: contain;
21
20
  }
@@ -9,7 +9,7 @@ const Logo = ({ icon, text, className }) => {
9
9
  const imageData = getMediaImage(icon);
10
10
  return (React.createElement(RouterLink, { href: "/", passHref: true },
11
11
  React.createElement("div", { className: b(null, className) },
12
- imageData && React.createElement(Image, Object.assign({}, imageData)),
12
+ imageData && React.createElement(Image, Object.assign({ className: b('icon') }, imageData)),
13
13
  React.createElement("span", { className: b('text') }, text))));
14
14
  };
15
15
  export default Logo;
@@ -28,6 +28,7 @@ unpredictable css rules order in build */
28
28
  margin-left: 5px;
29
29
  }
30
30
  .navigation-item__icon {
31
+ display: flex;
31
32
  width: 20px;
32
33
  height: 20px;
33
34
  margin-right: 8px;
@@ -1,5 +1,5 @@
1
1
  import React, { MouseEventHandler } from 'react';
2
- import { NavigationButtonItem, NavigationDropdownItem, NavigationSocialItem, NavigationLinkItem } from '../../../../models/navigation';
2
+ import { NavigationButtonItem, NavigationDropdownItem, NavigationSocialItem, NavigationLinkItem } from '../../../../models';
3
3
  import './NavigationItem.css';
4
4
  declare type DropdownItemData = Omit<NavigationDropdownItem, 'items'>;
5
5
  export declare type NavigationItemData = NavigationLinkItem | NavigationButtonItem | NavigationSocialItem | DropdownItemData;
@@ -8,6 +8,7 @@ export interface NavigationItemProps {
8
8
  className?: string;
9
9
  onClick?: MouseEventHandler;
10
10
  isOpened?: boolean;
11
+ hostname?: string;
11
12
  }
12
13
  declare const NavigationItem: React.FC<NavigationItemProps>;
13
14
  export default NavigationItem;
@@ -1,17 +1,17 @@
1
1
  import { __rest } from "tslib";
2
2
  import React, { Fragment, useContext, useMemo } from 'react';
3
3
  import block from 'bem-cn-lite';
4
- import { RouterLink, ToggleArrow } from '../../../index';
4
+ import { RouterLink, ToggleArrow, Button, Image } from '../../../index';
5
5
  import { getLinkProps } from '../../../../utils';
6
6
  import { LocationContext } from '../../../../context/locationContext';
7
- import { NavigationItemType, } from '../../../../models/navigation';
7
+ import { NavigationItemType, } from '../../../../models';
8
8
  import { NavigationArrow } from '../../../../icons';
9
9
  import SocialIcon from '../SocialIcon/SocialIcon';
10
10
  import { getMediaImage } from '../../../Media/Image/utils';
11
11
  import './NavigationItem.css';
12
12
  const b = block('navigation-item');
13
13
  const Content = ({ text, icon }) => (React.createElement(Fragment, null,
14
- icon && React.createElement("img", Object.assign({ className: b('icon') }, icon)),
14
+ icon && React.createElement(Image, Object.assign({ className: b('icon') }, icon)),
15
15
  React.createElement("span", { className: b('text') }, text)));
16
16
  const NavigationDropdown = (_a) => {
17
17
  var { text, icon, isOpened } = _a, props = __rest(_a, ["text", "icon", "isOpened"]);
@@ -21,9 +21,10 @@ const NavigationDropdown = (_a) => {
21
21
  React.createElement(ToggleArrow, { className: b('dropdown'), size: 12, type: 'vertical', iconType: "navigation", open: isOpened })));
22
22
  };
23
23
  const NavigationLink = (props) => {
24
- const { hostname } = useContext(LocationContext);
25
- const { url, text, icon, arrow, target } = props, rest = __rest(props, ["url", "text", "icon", "arrow", "target"]);
26
- const linkExtraProps = getLinkProps(url, hostname, target);
24
+ const { hostname: locationHostname } = useContext(LocationContext);
25
+ const { url, text, icon, arrow, target, hostname } = props, rest = __rest(props, ["url", "text", "icon", "arrow", "target", "hostname"]);
26
+ const currentHostname = locationHostname || hostname;
27
+ const linkExtraProps = getLinkProps(url, currentHostname, target);
27
28
  const iconData = icon && getMediaImage(icon);
28
29
  const content = (React.createElement(Fragment, null,
29
30
  React.createElement(Content, { text: text, icon: iconData }),
@@ -31,10 +32,15 @@ const NavigationLink = (props) => {
31
32
  return (linkExtraProps === null || linkExtraProps === void 0 ? void 0 : linkExtraProps.target) ? (React.createElement("a", Object.assign({ href: url, title: text }, rest, linkExtraProps), content)) : (React.createElement(RouterLink, { href: url, passHref: true },
32
33
  React.createElement("a", Object.assign({}, rest), content)));
33
34
  };
35
+ const NavigationButton = (props) => {
36
+ const { url, target } = props;
37
+ return target ? (React.createElement(Button, Object.assign({}, props, { url: url }))) : (React.createElement(RouterLink, { href: url },
38
+ React.createElement(Button, Object.assign({}, props, { url: url }))));
39
+ };
34
40
  //todo: add types support form component in map
35
41
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
36
42
  const NavigationItemsMap = {
37
- [NavigationItemType.Button]: RouterLink,
43
+ [NavigationItemType.Button]: NavigationButton,
38
44
  [NavigationItemType.Social]: SocialIcon,
39
45
  [NavigationItemType.Dropdown]: NavigationDropdown,
40
46
  [NavigationItemType.Link]: NavigationLink,
@@ -0,0 +1,25 @@
1
+ import React, { RefObject } from 'react';
2
+ import { NavigationLinkItem } from '../../../../models/navigation';
3
+ import './NavigationPopup.css';
4
+ export interface NavigationPopupProps {
5
+ items: NavigationLinkItem[];
6
+ onClose: () => void;
7
+ left?: number;
8
+ className?: string;
9
+ }
10
+ interface NavigationPopupState {
11
+ calculatedLeft?: number;
12
+ }
13
+ export default class NavigationPopup extends React.Component<NavigationPopupProps, NavigationPopupState> {
14
+ ref: RefObject<HTMLDivElement>;
15
+ state: {
16
+ calculatedLeft: number | undefined;
17
+ };
18
+ private calculateLeft;
19
+ componentDidMount(): void;
20
+ componentDidUpdate(prevProps: NavigationPopupProps): void;
21
+ componentWillUnmount(): void;
22
+ render(): JSX.Element | null;
23
+ private renderDefaultPopup;
24
+ }
25
+ export {};
@@ -0,0 +1,54 @@
1
+ import _ from 'lodash';
2
+ import block from 'bem-cn-lite';
3
+ import React, { Fragment, createRef } from 'react';
4
+ import { Portal } from '@gravity-ui/uikit';
5
+ import { OutsideClick } from '../../../index';
6
+ import NavigationItem from '../NavigationItem/NavigationItem';
7
+ import './NavigationPopup.css';
8
+ const b = block('navigation-popup');
9
+ export default class NavigationPopup extends React.Component {
10
+ constructor() {
11
+ super(...arguments);
12
+ this.ref = createRef();
13
+ this.state = {
14
+ calculatedLeft: this.props.left,
15
+ };
16
+ this.calculateLeft = _.debounce(() => {
17
+ const { left } = this.props;
18
+ if (this.ref && this.ref.current && left) {
19
+ const right = left + this.ref.current.offsetWidth;
20
+ const docWidth = document.body.clientWidth;
21
+ const calculatedLeft = right > docWidth ? left - (right - docWidth) : left;
22
+ this.setState({ calculatedLeft });
23
+ }
24
+ else {
25
+ this.setState({ calculatedLeft: left });
26
+ }
27
+ }, 100);
28
+ }
29
+ componentDidMount() {
30
+ this.calculateLeft();
31
+ window.addEventListener('resize', this.calculateLeft);
32
+ }
33
+ componentDidUpdate(prevProps) {
34
+ if (prevProps.left !== this.props.left) {
35
+ this.calculateLeft();
36
+ }
37
+ }
38
+ componentWillUnmount() {
39
+ window.removeEventListener('resize', this.calculateLeft);
40
+ }
41
+ render() {
42
+ if (!document || !document.body) {
43
+ return null;
44
+ }
45
+ const { onClose } = this.props;
46
+ const { calculatedLeft } = this.state;
47
+ return (React.createElement(Portal, null,
48
+ React.createElement("div", { ref: this.ref, className: b(), style: { left: calculatedLeft } },
49
+ React.createElement(OutsideClick, { onOutsideClick: onClose }, this.renderDefaultPopup()))));
50
+ }
51
+ renderDefaultPopup() {
52
+ return (React.createElement(Fragment, null, this.props.items.map((item) => (React.createElement(NavigationItem, { key: item.text, className: b('link'), data: item })))));
53
+ }
54
+ }
@@ -1,5 +1,5 @@
1
- import React, { RefObject } from 'react';
2
- import { NavigationLinkItem } from '../../../../models/navigation';
1
+ import React from 'react';
2
+ import { NavigationLinkItem } from '../../../../models';
3
3
  import './NavigationPopup.css';
4
4
  export interface NavigationPopupProps {
5
5
  items: NavigationLinkItem[];
@@ -7,19 +7,5 @@ export interface NavigationPopupProps {
7
7
  left?: number;
8
8
  className?: string;
9
9
  }
10
- interface NavigationPopupState {
11
- calculatedLeft?: number;
12
- }
13
- export default class NavigationPopup extends React.Component<NavigationPopupProps, NavigationPopupState> {
14
- ref: RefObject<HTMLDivElement>;
15
- state: {
16
- calculatedLeft: number | undefined;
17
- };
18
- private calculateLeft;
19
- componentDidMount(): void;
20
- componentDidUpdate(prevProps: NavigationPopupProps): void;
21
- componentWillUnmount(): void;
22
- render(): JSX.Element | null;
23
- private renderDefaultPopup;
24
- }
25
- export {};
10
+ export declare const NavigationPopup: React.FC<NavigationPopupProps>;
11
+ export default NavigationPopup;
@@ -1,54 +1,44 @@
1
1
  import _ from 'lodash';
2
2
  import block from 'bem-cn-lite';
3
- import React, { Fragment, createRef } from 'react';
3
+ import React, { Fragment, useRef, useState, useEffect, useCallback, useContext } from 'react';
4
4
  import { Portal } from '@gravity-ui/uikit';
5
5
  import { OutsideClick } from '../../../index';
6
6
  import NavigationItem from '../NavigationItem/NavigationItem';
7
7
  import './NavigationPopup.css';
8
+ import { LocationContext } from '../../../../context/locationContext';
8
9
  const b = block('navigation-popup');
9
- export default class NavigationPopup extends React.Component {
10
- constructor() {
11
- super(...arguments);
12
- this.ref = createRef();
13
- this.state = {
14
- calculatedLeft: this.props.left,
15
- };
16
- this.calculateLeft = _.debounce(() => {
17
- const { left } = this.props;
18
- if (this.ref && this.ref.current && left) {
19
- const right = left + this.ref.current.offsetWidth;
20
- const docWidth = document.body.clientWidth;
21
- const calculatedLeft = right > docWidth ? left - (right - docWidth) : left;
22
- this.setState({ calculatedLeft });
23
- }
24
- else {
25
- this.setState({ calculatedLeft: left });
26
- }
27
- }, 100);
28
- }
29
- componentDidMount() {
30
- this.calculateLeft();
31
- window.addEventListener('resize', this.calculateLeft);
32
- }
33
- componentDidUpdate(prevProps) {
34
- if (prevProps.left !== this.props.left) {
35
- this.calculateLeft();
10
+ export const NavigationPopup = ({ items, left, onClose }) => {
11
+ const [calculatedLeft, setCalculatedLeft] = useState(left);
12
+ const popupRef = useRef(null);
13
+ const { hostname } = useContext(LocationContext);
14
+ const calculateLeft = useCallback(() => {
15
+ if (popupRef && popupRef.current && left) {
16
+ const right = left + popupRef.current.offsetWidth;
17
+ const docWidth = document.body.clientWidth;
18
+ const currentLeft = right > docWidth ? left - (right - docWidth) : left;
19
+ setCalculatedLeft(currentLeft);
36
20
  }
37
- }
38
- componentWillUnmount() {
39
- window.removeEventListener('resize', this.calculateLeft);
40
- }
41
- render() {
42
- if (!document || !document.body) {
43
- return null;
21
+ else {
22
+ setCalculatedLeft(left);
44
23
  }
45
- const { onClose } = this.props;
46
- const { calculatedLeft } = this.state;
47
- return (React.createElement(Portal, null,
48
- React.createElement("div", { ref: this.ref, className: b(), style: { left: calculatedLeft } },
49
- React.createElement(OutsideClick, { onOutsideClick: onClose }, this.renderDefaultPopup()))));
50
- }
51
- renderDefaultPopup() {
52
- return (React.createElement(Fragment, null, this.props.items.map((item) => (React.createElement(NavigationItem, { key: item.text, className: b('link'), data: item })))));
24
+ }, [left]);
25
+ useEffect(() => {
26
+ const debounceCalculateLeft = _.debounce(calculateLeft, 100);
27
+ calculateLeft();
28
+ window.addEventListener('resize', debounceCalculateLeft);
29
+ return () => {
30
+ window.removeEventListener('resize', debounceCalculateLeft);
31
+ };
32
+ }, [calculateLeft]);
33
+ useEffect(() => {
34
+ calculateLeft();
35
+ }, [calculateLeft, left]);
36
+ if (!document || !document.body) {
37
+ return null;
53
38
  }
54
- }
39
+ const renderDefaultPopup = (React.createElement(Fragment, null, items.map((item) => (React.createElement(NavigationItem, { key: item.text, className: b('link'), data: item, hostname: hostname })))));
40
+ return (React.createElement(Portal, null,
41
+ React.createElement("div", { ref: popupRef, className: b(), style: { left: calculatedLeft } },
42
+ React.createElement(OutsideClick, { onOutsideClick: onClose }, renderDefaultPopup))));
43
+ };
44
+ export default NavigationPopup;
@@ -15,6 +15,7 @@ export interface NavigationLinkItem extends NavigationItemBase {
15
15
  url: string;
16
16
  arrow?: boolean;
17
17
  target?: string;
18
+ hostname?: string;
18
19
  }
19
20
  export interface NavigationButtonItem extends ButtonProps {
20
21
  type: NavigationItemType.Button;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/page-constructor",
3
- "version": "1.7.0-alpha.2",
3
+ "version": "1.7.0-alpha.4",
4
4
  "description": "Gravity UI Page Constructor",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -15,6 +15,7 @@ export interface NavigationLinkItem extends NavigationItemBase {
15
15
  url: string;
16
16
  arrow?: boolean;
17
17
  target?: string;
18
+ hostname?: string;
18
19
  }
19
20
  export interface NavigationButtonItem extends ButtonProps {
20
21
  type: NavigationItemType.Button;