@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
@@ -1,26 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.NavigationListItem = void 0;
4
3
  const tslib_1 = require("tslib");
5
4
  const react_1 = tslib_1.__importDefault(require("react"));
6
- const models_1 = require("../../../models");
7
- const utils_1 = require("../../../utils");
8
- const utils_2 = require("../../utils");
9
- const NavigationDropdownItem_1 = tslib_1.__importDefault(require("../NavigationDropdownItem/NavigationDropdownItem"));
5
+ const utils_1 = require("../../utils");
10
6
  const NavigationItem_1 = tslib_1.__importDefault(require("../NavigationItem/NavigationItem"));
11
- const b = (0, utils_1.block)('navigation-list-item');
12
- const NavigationListItem = ({ item, className, index, activeItemId, highlightActiveItem, hidePopup, column, onActiveItemChange, }) => {
7
+ const NavigationListItem = (_a) => {
8
+ var { column, index, activeItemId, onActiveItemChange } = _a, props = tslib_1.__rest(_a, ["column", "index", "activeItemId", "onActiveItemChange"]);
13
9
  const id = `${column}-${index}`;
14
10
  const isActive = id === activeItemId;
15
- const onClick = (0, utils_2.getItemClickHandler)({
11
+ const onClick = (0, utils_1.getItemClickHandler)({
16
12
  column,
17
13
  index,
18
14
  activeItemId,
19
15
  onActiveItemChange,
20
16
  });
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 })),
23
- highlightActiveItem && isActive && (react_1.default.createElement("div", { className: b('slider-container') },
24
- react_1.default.createElement("div", { className: b('slider') })))));
17
+ return (react_1.default.createElement(NavigationItem_1.default, Object.assign({ isActive: isActive, onClick: onClick, hidePopup: onActiveItemChange }, props)));
25
18
  };
26
- exports.NavigationListItem = NavigationListItem;
19
+ exports.default = NavigationListItem;
@@ -14,13 +14,14 @@ unpredictable css rules order in build */
14
14
  background: var(--yc-color-base-float);
15
15
  box-shadow: 0 3px 10px var(--yc-color-sfx-shadow);
16
16
  }
17
- @media (max-width: 768px) {
18
- .pc-navigation-popup {
19
- display: none;
20
- }
17
+ .pc-navigation-popup__list {
18
+ margin: 0;
19
+ padding: 0;
20
+ list-style: none;
21
21
  }
22
22
  .pc-navigation-popup__link {
23
23
  height: 36px;
24
+ line-height: 20px;
24
25
  padding: 8px 12px;
25
26
  border-radius: 8px;
26
27
  }
@@ -1,11 +1,4 @@
1
1
  import React from 'react';
2
- import { NavigationLinkItem } from '../../../models';
3
- export interface NavigationPopupProps {
4
- open: boolean;
5
- items: NavigationLinkItem[];
6
- onClose: () => void;
7
- className?: string;
8
- anchorRef: React.RefObject<Element>;
9
- }
2
+ import { NavigationPopupProps } from '../../models';
10
3
  export declare const NavigationPopup: React.FC<NavigationPopupProps>;
11
4
  export default NavigationPopup;
@@ -5,15 +5,15 @@ const tslib_1 = require("tslib");
5
5
  const react_1 = tslib_1.__importDefault(require("react"));
6
6
  const uikit_1 = require("@gravity-ui/uikit");
7
7
  const utils_1 = require("../../../utils");
8
+ const models_1 = require("../../models");
8
9
  const NavigationItem_1 = tslib_1.__importDefault(require("../NavigationItem/NavigationItem"));
9
10
  const b = (0, utils_1.block)('navigation-popup');
10
11
  const OFFSET_RESET = [0, 0];
11
- const NavigationPopup = ({ anchorRef, items, onClose, className, open, }) => {
12
- return (react_1.default.createElement(uikit_1.Popup
12
+ const NavigationPopup = ({ anchorRef, items, onClose, className, open, }) => (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
+ , {
13
15
  // 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 })))));
17
- };
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 },
17
+ react_1.default.createElement("ul", { className: b('list') }, items.map((item) => (react_1.default.createElement(NavigationItem_1.default, { key: item.text, className: b('link'), data: item, menuLayout: models_1.NavigationLayout.Dropdown }))))));
18
18
  exports.NavigationPopup = NavigationPopup;
19
19
  exports.default = exports.NavigationPopup;
@@ -3,9 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const react_1 = tslib_1.__importDefault(require("react"));
5
5
  const utils_1 = require("../../../utils");
6
- const Header_1 = tslib_1.__importDefault(require("../../components/Header/Header"));
6
+ const Navigation_1 = tslib_1.__importDefault(require("../../components/Navigation/Navigation"));
7
7
  const b = (0, utils_1.block)('layout');
8
8
  const Layout = ({ children, navigation }) => (react_1.default.createElement("div", { className: b() },
9
- navigation && react_1.default.createElement(Header_1.default, { data: navigation.header, logo: navigation.logo }),
9
+ navigation && react_1.default.createElement(Navigation_1.default, { data: navigation.header, logo: navigation.logo }),
10
10
  react_1.default.createElement("main", { className: b('content') }, children)));
11
11
  exports.default = Layout;
@@ -0,0 +1,63 @@
1
+ import { MouseEventHandler } from 'react';
2
+ import { ClassNameProps, NavigationItemData, NavigationItemModel, NavigationLinkItem, ThemedNavigationLogoData } from '../models';
3
+ export interface MobileMenuButtonProps {
4
+ isSidebarOpened: boolean;
5
+ onSidebarOpenedChange: (arg: boolean) => void;
6
+ }
7
+ export declare enum ItemColumnName {
8
+ Left = "left",
9
+ Right = "right",
10
+ Top = "top",
11
+ Bottom = "bottom"
12
+ }
13
+ export declare enum NavigationLayout {
14
+ Desktop = "desktop",
15
+ Mobile = "mobile",
16
+ Dropdown = "dropdown"
17
+ }
18
+ export interface ActiveItemProps {
19
+ activeItemId?: string;
20
+ onActiveItemChange: (id?: string) => void;
21
+ }
22
+ export interface MenuLayoutProps {
23
+ menuLayout?: NavigationLayout;
24
+ }
25
+ export interface NavigationItemProps extends ClassNameProps, MenuLayoutProps {
26
+ data: NavigationItemData;
27
+ onClick?: MouseEventHandler;
28
+ isActive?: boolean;
29
+ isTopLevel?: boolean;
30
+ hidePopup?: () => void;
31
+ }
32
+ export interface NavigationListItemProps extends MenuLayoutProps, ActiveItemProps, ClassNameProps {
33
+ data: NavigationItemModel;
34
+ column: ItemColumnName;
35
+ index: number;
36
+ }
37
+ export interface NavigationListProps extends Pick<NavigationListItemProps, 'column'>, MenuLayoutProps, ActiveItemProps, ClassNameProps {
38
+ items: NavigationItemModel[];
39
+ itemClassName?: string;
40
+ }
41
+ export interface ItemsWrapperProps extends Pick<NavigationListProps, 'items'>, ActiveItemProps, ClassNameProps {
42
+ }
43
+ export interface DesktopNavigationProps extends MobileMenuButtonProps, ActiveItemProps {
44
+ logo: ThemedNavigationLogoData;
45
+ leftItemsWithIconSize: NavigationItemModel[];
46
+ rightItemsWithIconSize?: NavigationItemModel[];
47
+ }
48
+ export interface MobileNavigationProps extends ClassNameProps, ActiveItemProps {
49
+ isOpened?: boolean;
50
+ topItems?: NavigationItemModel[];
51
+ bottomItems?: NavigationItemModel[];
52
+ }
53
+ export interface NavigationProps extends MobileMenuButtonProps, ActiveItemProps {
54
+ logo: ThemedNavigationLogoData;
55
+ leftItemsWithIconSize: NavigationItemModel[];
56
+ rightItemsWithIconSize?: NavigationItemModel[];
57
+ }
58
+ export interface NavigationPopupProps extends ClassNameProps {
59
+ open: boolean;
60
+ items: NavigationLinkItem[];
61
+ onClose: () => void;
62
+ anchorRef: React.RefObject<Element>;
63
+ }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ItemColumnName = void 0;
3
+ exports.NavigationLayout = exports.ItemColumnName = void 0;
4
4
  var ItemColumnName;
5
5
  (function (ItemColumnName) {
6
6
  ItemColumnName["Left"] = "left";
@@ -8,3 +8,9 @@ var ItemColumnName;
8
8
  ItemColumnName["Top"] = "top";
9
9
  ItemColumnName["Bottom"] = "bottom";
10
10
  })(ItemColumnName = exports.ItemColumnName || (exports.ItemColumnName = {}));
11
+ var NavigationLayout;
12
+ (function (NavigationLayout) {
13
+ NavigationLayout["Desktop"] = "desktop";
14
+ NavigationLayout["Mobile"] = "mobile";
15
+ NavigationLayout["Dropdown"] = "dropdown";
16
+ })(NavigationLayout = exports.NavigationLayout || (exports.NavigationLayout = {}));
@@ -1,5 +1,6 @@
1
1
  import { MouseEventHandler } from 'react';
2
- import { ItemColumnName } from './constants';
2
+ import { NavigationButtonItem, NavigationDropdownItem, NavigationItemModel, NavigationItemType } from '../models';
3
+ import { ItemColumnName } from './models';
3
4
  type GetItemClickHandlerArgs = {
4
5
  column: ItemColumnName;
5
6
  index: number;
@@ -7,4 +8,13 @@ type GetItemClickHandlerArgs = {
7
8
  onActiveItemChange: (id?: string) => void;
8
9
  };
9
10
  export declare const getItemClickHandler: ({ column, index, onActiveItemChange, }: GetItemClickHandlerArgs) => MouseEventHandler;
11
+ export declare function getNavigationItemWithIconSize(iconSize?: number): (item: NavigationItemModel) => NavigationButtonItem | NavigationDropdownItem | {
12
+ type: NavigationItemType.Link;
13
+ url: string;
14
+ arrow?: boolean | undefined;
15
+ target?: string | undefined;
16
+ text: string;
17
+ icon?: import("../models").ImageProps | undefined;
18
+ iconSize?: number | undefined;
19
+ };
10
20
  export {};
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getItemClickHandler = void 0;
3
+ exports.getNavigationItemWithIconSize = exports.getItemClickHandler = void 0;
4
+ const models_1 = require("../models");
4
5
  const getItemClickHandler = ({ column, index, onActiveItemChange, activeItemId }) => (e) => {
5
6
  const id = `${column}-${index}`;
6
7
  if (e) {
@@ -9,3 +10,20 @@ const getItemClickHandler = ({ column, index, onActiveItemChange, activeItemId }
9
10
  onActiveItemChange(id === activeItemId ? undefined : `${column}-${index}`);
10
11
  };
11
12
  exports.getItemClickHandler = getItemClickHandler;
13
+ const isButtonItem = (item) => item.type === models_1.NavigationItemType.Button;
14
+ const isDropdownItem = (item) => item.type === models_1.NavigationItemType.Dropdown;
15
+ const iconSizeKey = 'iconSize';
16
+ function getNavigationItemWithIconSize(iconSize = 20) {
17
+ const getItem = (item) => {
18
+ const newItem = Object.assign({}, item);
19
+ if ('items' in newItem && isDropdownItem(newItem)) {
20
+ newItem.items = newItem.items.map(getItem);
21
+ }
22
+ if (!(iconSizeKey in newItem) && !isButtonItem(newItem)) {
23
+ newItem.iconSize = iconSize;
24
+ }
25
+ return newItem;
26
+ };
27
+ return getItem;
28
+ }
29
+ exports.getNavigationItemWithIconSize = getNavigationItemWithIconSize;
@@ -21,8 +21,9 @@ const Image = (props) => {
21
21
  useEffect(() => {
22
22
  if (parallax) {
23
23
  const handleScroll = () => setScrollY(window.scrollY);
24
- window.addEventListener('scroll', _.debounce(handleScroll, 5), { passive: true });
25
- return () => window.removeEventListener('scroll', _.debounce(handleScroll, 5));
24
+ const debouncedHandler = _.debounce(handleScroll, 5);
25
+ window.addEventListener('scroll', debouncedHandler, { passive: true });
26
+ return () => window.removeEventListener('scroll', debouncedHandler);
26
27
  }
27
28
  return () => { };
28
29
  });
@@ -1,15 +1,18 @@
1
1
  import React from 'react';
2
- import { Display, Pencil } from '@gravity-ui/icons';
2
+ import { Display, Pencil, Smartphone } from '@gravity-ui/icons';
3
3
  import { RadioButton } from '@gravity-ui/uikit';
4
4
  import { block } from '../../../utils';
5
+ import { Tablet } from '../../icons/Tablet';
5
6
  import { ViewModeItem } from '../../types';
6
7
  import i18n from './i18n';
7
- const ICON_SIZE = 14;
8
8
  import './ControlPanel.css';
9
+ const ICON_SIZE = 14;
9
10
  const b = block('control-panel');
10
11
  const ControlPanelViewModeIcons = {
11
12
  [ViewModeItem.Edititng]: Pencil,
12
- [ViewModeItem.View]: Display,
13
+ [ViewModeItem.Desktop]: Display,
14
+ [ViewModeItem.Tablet]: Tablet,
15
+ [ViewModeItem.Mobile]: Smartphone,
13
16
  };
14
17
  const ControlPanel = ({ viewMode = ViewModeItem.Edititng, onViewModeChange, className, }) => (React.createElement("div", { className: b(null, className) },
15
18
  React.createElement("div", { className: b('mode-switch') },
@@ -0,0 +1,7 @@
1
+ import { PropsWithChildren } from 'react';
2
+ import { ViewModeItem } from '../../types';
3
+ export interface DeviceEmulationProps extends PropsWithChildren {
4
+ mode: ViewModeItem;
5
+ }
6
+ declare const DeviceEmulation: ({ children, mode }: DeviceEmulationProps) => JSX.Element;
7
+ export default DeviceEmulation;
@@ -0,0 +1,7 @@
1
+ import React, { Fragment } from 'react';
2
+ import DeviceEmulationMobile from './DeviceEmulationMobile/DeviceEmulationMobile';
3
+ import { isMobileDevice, mobileDevices } from './utils';
4
+ const DeviceEmulation = ({ children, mode }) => (React.createElement(Fragment, null,
5
+ !isMobileDevice(mode) && children,
6
+ mobileDevices.map((device) => (React.createElement(DeviceEmulationMobile, { key: device, device: device, active: mode === device }, children)))));
7
+ export default DeviceEmulation;
@@ -0,0 +1,33 @@
1
+ .pc-device-emulation-mobile {
2
+ position: absolute;
3
+ top: 0;
4
+ left: 0;
5
+ width: 100%;
6
+ display: flex;
7
+ justify-content: center;
8
+ opacity: 0;
9
+ pointer-events: none;
10
+ }
11
+ .pc-device-emulation-mobile_active {
12
+ opacity: 1;
13
+ pointer-events: all;
14
+ }
15
+ .pc-device-emulation-mobile__frame {
16
+ border: none;
17
+ }
18
+ .pc-device-emulation-mobile__frame_device_mobile {
19
+ width: 390px;
20
+ height: 844px;
21
+ }
22
+ .pc-device-emulation-mobile__frame_device_tablet {
23
+ width: 768px;
24
+ height: 1024px;
25
+ }
26
+
27
+ .pc-device-emulation-mobile__frame {
28
+ margin: 0;
29
+ }
30
+
31
+ .pc-device-emulation-mobile__container {
32
+ overflow: auto;
33
+ }
@@ -0,0 +1,9 @@
1
+ import { PropsWithChildren } from 'react';
2
+ import { MobileDevice } from '../utils';
3
+ import './DeviceEmulationMobile.css';
4
+ interface DeviceEmulationMobileProps extends PropsWithChildren {
5
+ device: MobileDevice;
6
+ active: boolean;
7
+ }
8
+ declare const DeviceEmulationMobile: ({ device, active }: DeviceEmulationMobileProps) => JSX.Element;
9
+ export default DeviceEmulationMobile;
@@ -0,0 +1,40 @@
1
+ import { __rest } from "tslib";
2
+ import React, { useContext, useEffect, useRef } from 'react';
3
+ import { block } from '../../../../utils';
4
+ import { EditorContext } from '../../../context';
5
+ import { DeviceIframe } from '../../../widget';
6
+ import './DeviceEmulationMobile.css';
7
+ const b = block('device-emulation-mobile');
8
+ const DeviceEmulationMobile = ({ device, active }) => {
9
+ const _a = useContext(EditorContext), { deviceEmulationSettings } = _a, initialData = __rest(_a, ["deviceEmulationSettings"]);
10
+ const containerRef = useRef(null);
11
+ const deviceIframeRef = useRef(null);
12
+ useEffect(() => {
13
+ let iframe;
14
+ if (containerRef === null || containerRef === void 0 ? void 0 : containerRef.current) {
15
+ iframe = new DeviceIframe(containerRef === null || containerRef === void 0 ? void 0 : containerRef.current, {
16
+ initialData,
17
+ className: b('frame', { device }),
18
+ settings: deviceEmulationSettings,
19
+ });
20
+ deviceIframeRef.current = iframe;
21
+ }
22
+ return () => {
23
+ iframe === null || iframe === void 0 ? void 0 : iframe.destroy();
24
+ };
25
+ // render iframe only once, then update it's data with postMessage
26
+ // eslint-disable-next-line react-hooks/exhaustive-deps
27
+ }, [device]);
28
+ useEffect(() => {
29
+ if (deviceIframeRef.current) {
30
+ deviceIframeRef.current.onActivenessUpdate(active);
31
+ }
32
+ }, [active]);
33
+ useEffect(() => {
34
+ if (deviceIframeRef.current && initialData) {
35
+ deviceIframeRef.current.onDataUpdate(initialData);
36
+ }
37
+ }, [initialData]);
38
+ return React.createElement("div", { className: b({ active, device }), ref: containerRef });
39
+ };
40
+ export default DeviceEmulationMobile;
@@ -0,0 +1,4 @@
1
+ import { ViewModeItem } from '../../types';
2
+ export type MobileDevice = ViewModeItem.Mobile | ViewModeItem.Tablet;
3
+ export declare const mobileDevices: readonly [ViewModeItem.Tablet, ViewModeItem.Mobile];
4
+ export declare const isMobileDevice: (mode: ViewModeItem) => mode is MobileDevice;
@@ -0,0 +1,3 @@
1
+ import { ViewModeItem } from '../../types';
2
+ export const mobileDevices = [ViewModeItem.Tablet, ViewModeItem.Mobile];
3
+ export const isMobileDevice = (mode) => [ViewModeItem.Tablet, ViewModeItem.Mobile].includes(mode);
@@ -2,6 +2,7 @@ import React, { Children, Fragment } from 'react';
2
2
  import { block } from '../../../utils';
3
3
  import { ViewModeItem } from '../../types';
4
4
  import ControlPanel from '../ControlPanel/ControlPanel';
5
+ import DeviceEmulation from '../DeviceEmulation/DeviceEmulation';
5
6
  import './Layout.css';
6
7
  const b = block('editor-layout');
7
8
  const Left = () => null;
@@ -27,7 +28,8 @@ const Layout = ({ children, mode, onModeChange }) => {
27
28
  React.createElement("div", { className: b('container') },
28
29
  React.createElement(Fragment, null,
29
30
  left && React.createElement("div", { className: b('left') }, left),
30
- right && React.createElement("div", { className: b('right', { editing: isEditingMode }) }, right)))));
31
+ right && (React.createElement("div", { className: b('right', { editing: isEditingMode }) },
32
+ React.createElement(DeviceEmulation, { mode: mode }, right)))))));
31
33
  };
32
34
  Layout.Left = Left;
33
35
  Layout.Right = Right;
@@ -1,2 +1,2 @@
1
1
  import { EditorProps } from '../../types';
2
- export declare const Editor: ({ children, customSchema, onChange, ...rest }: EditorProps) => JSX.Element;
2
+ export declare const Editor: ({ customSchema, onChange, providerProps, transformContent, deviceEmulationSettings, ...rest }: EditorProps) => JSX.Element;
@@ -1,20 +1,23 @@
1
1
  import { __rest } from "tslib";
2
2
  import React, { useEffect, useMemo } from 'react';
3
+ import { PageConstructor, PageConstructorProvider } from '../../../containers/PageConstructor';
3
4
  import AddBlock from '../../components/AddBlock/AddBlock';
4
5
  import EditBlock from '../../components/EditBlock/EditBlock';
5
6
  import { ErrorBoundary } from '../../components/ErrorBoundary/ErrorBoundary';
6
7
  import Layout from '../../components/Layout/Layout';
7
8
  import { NotFoundBlock } from '../../components/NotFoundBlock/NotFoundBlock';
9
+ import { EditorContext } from '../../context';
8
10
  import useFormSpec from '../../hooks/useFormSpec';
9
11
  import { useEditorState } from '../../store';
10
12
  import { ViewModeItem } from '../../types';
11
- import { addCustomDecorator, getBlockId } from '../../utils';
13
+ import { addCustomDecorator, checkIsMobile, getBlockId } from '../../utils';
12
14
  import { Form } from '../Form/Form';
13
15
  export const Editor = (_a) => {
14
- var { children, customSchema, onChange } = _a, rest = __rest(_a, ["children", "customSchema", "onChange"]);
16
+ var { customSchema, onChange, providerProps, transformContent, deviceEmulationSettings } = _a, rest = __rest(_a, ["customSchema", "onChange", "providerProps", "transformContent", "deviceEmulationSettings"]);
15
17
  const { content, activeBlockIndex, errorBoundaryState, viewMode, onContentUpdate, onViewModeUpdate, onAdd, onSelect, injectEditBlockProps, } = useEditorState(rest);
16
18
  const formSpecs = useFormSpec(customSchema);
17
19
  const isEditingMode = viewMode === ViewModeItem.Edititng;
20
+ const transformedContent = useMemo(() => (transformContent ? transformContent(content, { viewMode }) : content), [content, transformContent, viewMode]);
18
21
  const outgoingProps = useMemo(() => {
19
22
  const custom = isEditingMode
20
23
  ? addCustomDecorator([
@@ -24,15 +27,37 @@ export const Editor = (_a) => {
24
27
  (props) => (React.createElement(ErrorBoundary, Object.assign({}, props, { key: `${getBlockId(props)}-${errorBoundaryState}` }))),
25
28
  ], rest.custom)
26
29
  : rest.custom;
27
- return { content, custom, viewMode };
28
- }, [injectEditBlockProps, content, errorBoundaryState, isEditingMode, viewMode, rest.custom]);
30
+ return {
31
+ content: transformedContent,
32
+ custom,
33
+ viewMode,
34
+ };
35
+ }, [
36
+ injectEditBlockProps,
37
+ errorBoundaryState,
38
+ isEditingMode,
39
+ viewMode,
40
+ transformedContent,
41
+ rest.custom,
42
+ ]);
43
+ const context = useMemo(() => ({
44
+ constructorProps: {
45
+ content: transformedContent,
46
+ custom: rest.custom,
47
+ },
48
+ providerProps: Object.assign(Object.assign({}, providerProps), { isMobile: checkIsMobile(viewMode) }),
49
+ deviceEmulationSettings,
50
+ }), [providerProps, rest.custom, viewMode, transformedContent, deviceEmulationSettings]);
29
51
  useEffect(() => {
30
52
  onChange === null || onChange === void 0 ? void 0 : onChange(content);
31
53
  }, [content, onChange]);
32
- return (React.createElement(Layout, { mode: viewMode, onModeChange: onViewModeUpdate },
33
- isEditingMode && (React.createElement(Layout.Left, null,
34
- React.createElement(Form, { content: content, onChange: onContentUpdate, activeBlockIndex: activeBlockIndex, onSelect: onSelect, spec: formSpecs }))),
35
- React.createElement(Layout.Right, null,
36
- React.createElement(ErrorBoundary, { key: errorBoundaryState }, children(outgoingProps)),
37
- isEditingMode && React.createElement(AddBlock, { onAdd: onAdd }))));
54
+ return (React.createElement(EditorContext.Provider, { value: context },
55
+ React.createElement(Layout, { mode: viewMode, onModeChange: onViewModeUpdate },
56
+ isEditingMode && (React.createElement(Layout.Left, null,
57
+ React.createElement(Form, { content: content, onChange: onContentUpdate, activeBlockIndex: activeBlockIndex, onSelect: onSelect, spec: formSpecs }))),
58
+ React.createElement(Layout.Right, null,
59
+ React.createElement(ErrorBoundary, { key: errorBoundaryState },
60
+ React.createElement(PageConstructorProvider, Object.assign({}, providerProps),
61
+ React.createElement(PageConstructor, Object.assign({}, outgoingProps)))),
62
+ isEditingMode && React.createElement(AddBlock, { onAdd: onAdd })))));
38
63
  };
@@ -28,8 +28,8 @@ export const Form = memo(({ content, onChange, activeBlockIndex, onSelect, spec
28
28
  break;
29
29
  }
30
30
  case FormTab.Blocks: {
31
- form = (React.createElement(Fragment, null, blocks.map((blockData, index) => blocksSpec[blockData.type] ? (React.createElement("div", { className: b('block-form') },
32
- React.createElement(BlockForm, { spec: blocksSpec[blockData.type], key: getBlockKey(blockData, index), data: blockData, active: activeBlockIndex === index, onChange: (data) => {
31
+ form = (React.createElement(Fragment, null, blocks.map((blockData, index) => blocksSpec[blockData.type] ? (React.createElement("div", { className: b('block-form'), key: getBlockKey(blockData, index) },
32
+ React.createElement(BlockForm, { spec: blocksSpec[blockData.type], data: blockData, active: activeBlockIndex === index, onChange: (data) => {
33
33
  onChange(Object.assign(Object.assign({}, content), { blocks: [
34
34
  ...blocks.slice(0, index),
35
35
  data,
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import { PageConstructorProps, PageConstructorProviderProps } from '../containers/PageConstructor';
3
+ import { EditorProps } from './types';
4
+ export interface EditorContextType {
5
+ constructorProps?: PageConstructorProps;
6
+ providerProps?: PageConstructorProviderProps;
7
+ deviceEmulationSettings?: EditorProps['deviceEmulationSettings'];
8
+ }
9
+ export declare const EditorContext: React.Context<Partial<EditorContextType>>;
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export const EditorContext = React.createContext({});
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export declare const Tablet: React.FC<React.SVGProps<SVGSVGElement>>;
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { a11yHiddenSvgProps } from '../../utils/svg';
3
+ export const Tablet = (props) => (React.createElement("svg", Object.assign({ xmlns: "http://www.w3.org/2000/svg", width: "12", height: "14", viewBox: "0 0 12 14", fill: "none" }, a11yHiddenSvgProps, props),
4
+ React.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M10.5 3L10.5 11C10.5 11.8284 9.82843 12.5 9 12.5L3 12.5C2.17157 12.5 1.5 11.8284 1.5 11L1.5 3C1.5 2.17157 2.17157 1.5 3 1.5L9 1.5C9.82843 1.5 10.5 2.17157 10.5 3ZM9 -1.31134e-07C10.6569 -5.87108e-08 12 1.34315 12 3L12 11C12 12.6569 10.6569 14 9 14L3 14C1.34315 14 4.00426e-07 12.6569 4.72849e-07 11L8.2254e-07 3C8.94964e-07 1.34315 1.34315 -4.65826e-07 3 -3.93403e-07L9 -1.31134e-07ZM3.75 9.5C3.33579 9.5 3 9.83579 3 10.25C3 10.6642 3.33579 11 3.75 11L8.25 11C8.66421 11 9 10.6642 9 10.25C9 9.83579 8.66421 9.5 8.25 9.5L3.75 9.5Z", fill: "currentColor", fillOpacity: "0.85" })));
@@ -1,16 +1,22 @@
1
- /// <reference types="react" />
2
- import { PageConstructorProps } from '../../containers/PageConstructor';
1
+ import { PageConstructorProps, PageConstructorProviderProps } from '../../containers/PageConstructor';
3
2
  import { BlockDecorationProps, PageContent } from '../../models';
4
3
  import { SchemaCustomConfig } from '../../schema';
5
4
  import { EditBlockActions } from '../components/EditBlock/EditBlock';
6
5
  export type EditorBlockId = number | string;
7
- export interface EditorOutgoingProps extends Partial<PageConstructorProps> {
6
+ interface ContentTransformersOptions {
8
7
  viewMode: ViewModeItem;
9
8
  }
9
+ export type ContentTransformer = (content: PageContent, options: ContentTransformersOptions) => PageContent;
10
+ export interface DeviceEmulationSettings {
11
+ customStyles?: string;
12
+ applyHostStyles?: boolean;
13
+ }
10
14
  export interface EditorProps extends Required<Pick<PageConstructorProps, 'content'>>, Partial<Omit<PageConstructorProps, 'content'>> {
11
- children: (props: EditorOutgoingProps) => React.ReactNode;
15
+ providerProps?: PageConstructorProviderProps;
12
16
  onChange?: (data: PageContent) => void;
17
+ transformContent?: ContentTransformer;
13
18
  customSchema?: SchemaCustomConfig;
19
+ deviceEmulationSettings?: DeviceEmulationSettings;
14
20
  }
15
21
  export interface EditBlockEditorProps {
16
22
  isActive?: boolean;
@@ -22,5 +28,8 @@ export interface EditBlockProps extends EditBlockEditorProps, BlockDecorationPro
22
28
  }
23
29
  export declare enum ViewModeItem {
24
30
  Edititng = "editing",
25
- View = "view"
31
+ Desktop = "desktop",
32
+ Tablet = "tablet",
33
+ Mobile = "mobile"
26
34
  }
35
+ export {};
@@ -1,5 +1,7 @@
1
1
  export var ViewModeItem;
2
2
  (function (ViewModeItem) {
3
3
  ViewModeItem["Edititng"] = "editing";
4
- ViewModeItem["View"] = "view";
4
+ ViewModeItem["Desktop"] = "desktop";
5
+ ViewModeItem["Tablet"] = "tablet";
6
+ ViewModeItem["Mobile"] = "mobile";
5
7
  })(ViewModeItem || (ViewModeItem = {}));
@@ -1,4 +1,5 @@
1
1
  import { BlockDecorationProps, BlockDecorator, CustomConfig } from '../../models';
2
+ import { ViewModeItem } from '../types';
2
3
  export declare const formatBlockName: (name: string) => string;
3
4
  export declare const addCustomDecorator: (decorators: BlockDecorator[], custom?: CustomConfig) => {
4
5
  decorators: {
@@ -10,3 +11,4 @@ export declare const addCustomDecorator: (decorators: BlockDecorator[], custom?:
10
11
  loadable?: import("../../models").LoadableConfig | undefined;
11
12
  };
12
13
  export declare const getBlockId: ({ index, type }: BlockDecorationProps) => string;
14
+ export declare const checkIsMobile: (viewMode: ViewModeItem) => boolean;
@@ -1,7 +1,9 @@
1
1
  import _ from 'lodash';
2
+ import { ViewModeItem } from '../types';
2
3
  export const formatBlockName = (name) => _.capitalize(name).replace(/(block|-)/g, ' ');
3
4
  export const addCustomDecorator = (decorators, custom = {}) => {
4
5
  const customDecorators = custom.decorators || {};
5
6
  return Object.assign(Object.assign({}, custom), { decorators: Object.assign(Object.assign({}, customDecorators), { block: [...(customDecorators.block || []), ...decorators] }) });
6
7
  };
7
8
  export const getBlockId = ({ index, type }) => `${type}${index === undefined ? '' : `-${index}`}`;
9
+ export const checkIsMobile = (viewMode) => [ViewModeItem.Mobile, ViewModeItem.Tablet].includes(viewMode);
@@ -0,0 +1,4 @@
1
+ export declare const DeviceFrameMessageType: {
2
+ Ready: string;
3
+ Update: string;
4
+ };
@@ -0,0 +1,5 @@
1
+ const prefix = 'PC_EDITOR_DEVICE';
2
+ export const DeviceFrameMessageType = {
3
+ Ready: `${prefix}_MESSAGE_READY`,
4
+ Update: `${prefix}_MESSAGE_UPDATE`,
5
+ };
@@ -0,0 +1,21 @@
1
+ import { EditorContextType } from '../context';
2
+ import { DeviceEmulationSettings } from '../types';
3
+ interface DeviceIframeParams {
4
+ initialData?: EditorContextType;
5
+ className?: string;
6
+ settings?: DeviceEmulationSettings;
7
+ }
8
+ type InitialData = EditorContextType;
9
+ export declare class DeviceIframe {
10
+ iframeElement?: HTMLIFrameElement;
11
+ private initialData?;
12
+ private settings?;
13
+ constructor(parentElement: HTMLDivElement, { className, initialData, settings }: DeviceIframeParams);
14
+ onDataUpdate(data: InitialData): void;
15
+ onActivenessUpdate(active: boolean): void;
16
+ destroy(): void;
17
+ private addWidgetScript;
18
+ private addCustomStyles;
19
+ private onInit;
20
+ }
21
+ export {};