@gravity-ui/page-constructor 2.19.0 → 2.20.1

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 (114) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/build/cjs/components/BackgroundImage/BackgroundImage.js +2 -2
  3. package/build/cjs/components/BlockBase/BlockBase.d.ts +3 -2
  4. package/build/cjs/components/BlockBase/BlockBase.js +4 -2
  5. package/build/cjs/components/Image/Image.d.ts +1 -0
  6. package/build/cjs/components/Image/Image.js +2 -2
  7. package/build/cjs/containers/Loadable/Loadable.d.ts +2 -2
  8. package/build/cjs/containers/PageConstructor/PageConstructor.js +5 -3
  9. package/build/cjs/containers/PageConstructor/components/ConstructorBlocks/ConstructorBlocks.js +3 -2
  10. package/build/cjs/containers/PageConstructor/components/ConstructorItem/ConstructorItem.d.ts +1 -1
  11. package/build/cjs/containers/PageConstructor/components/ConstructorItem/ConstructorItem.js +5 -5
  12. package/build/cjs/context/innerContext/InnerContext.d.ts +2 -1
  13. package/build/cjs/customization/BlockDecoration.d.ts +3 -0
  14. package/build/cjs/customization/BlockDecoration.js +22 -0
  15. package/build/cjs/editor/Components/AddBlock/AddBlock.css +82 -0
  16. package/build/cjs/editor/Components/AddBlock/AddBlock.d.ts +7 -0
  17. package/build/cjs/editor/Components/AddBlock/AddBlock.js +43 -0
  18. package/build/cjs/editor/Components/EditBlock/EditBlock.css +47 -0
  19. package/build/cjs/editor/Components/EditBlock/EditBlock.d.ts +4 -0
  20. package/build/cjs/editor/Components/EditBlock/EditBlock.js +32 -0
  21. package/build/cjs/editor/Containers/Editor.d.ts +2 -0
  22. package/build/cjs/editor/Containers/Editor.js +24 -0
  23. package/build/cjs/editor/data/index.d.ts +13 -0
  24. package/build/cjs/editor/data/index.js +27 -0
  25. package/build/cjs/editor/data/previews/default-preview.d.ts +3 -0
  26. package/build/cjs/editor/data/previews/default-preview.js +18 -0
  27. package/build/cjs/editor/data/previews/header-block.d.ts +3 -0
  28. package/build/cjs/editor/data/previews/header-block.js +19 -0
  29. package/build/cjs/editor/index.d.ts +2 -0
  30. package/build/cjs/editor/index.js +7 -0
  31. package/build/cjs/editor/store/index.d.ts +15 -0
  32. package/build/cjs/editor/store/index.js +32 -0
  33. package/build/cjs/editor/store/reducer.d.ts +41 -0
  34. package/build/cjs/editor/store/reducer.js +59 -0
  35. package/build/cjs/editor/store/utils.d.ts +13 -0
  36. package/build/cjs/editor/store/utils.js +34 -0
  37. package/build/cjs/editor/styles/mixins.css +0 -0
  38. package/build/cjs/editor/styles/variables.css +0 -0
  39. package/build/cjs/editor/types/index.d.ts +17 -0
  40. package/build/cjs/editor/types/index.js +2 -0
  41. package/build/cjs/editor/utils/index.d.ts +11 -0
  42. package/build/cjs/editor/utils/index.js +12 -0
  43. package/build/cjs/models/constructor-items/blocks.d.ts +1 -11
  44. package/build/cjs/models/constructor-items/blocks.js +0 -2
  45. package/build/cjs/models/constructor-items/common.d.ts +1 -0
  46. package/build/cjs/models/constructor.d.ts +4 -1
  47. package/build/cjs/models/customization.d.ts +9 -0
  48. package/build/cjs/models/customization.js +2 -0
  49. package/build/cjs/models/index.d.ts +1 -0
  50. package/build/cjs/models/index.js +1 -0
  51. package/build/cjs/utils/blocks.d.ts +4 -1
  52. package/build/cjs/utils/blocks.js +11 -1
  53. package/build/esm/components/BackgroundImage/BackgroundImage.js +2 -2
  54. package/build/esm/components/BlockBase/BlockBase.d.ts +3 -2
  55. package/build/esm/components/BlockBase/BlockBase.js +4 -2
  56. package/build/esm/components/Image/Image.d.ts +1 -0
  57. package/build/esm/components/Image/Image.js +2 -2
  58. package/build/esm/containers/Loadable/Loadable.d.ts +2 -2
  59. package/build/esm/containers/PageConstructor/PageConstructor.js +6 -4
  60. package/build/esm/containers/PageConstructor/components/ConstructorBlocks/ConstructorBlocks.js +3 -2
  61. package/build/esm/containers/PageConstructor/components/ConstructorItem/ConstructorItem.d.ts +1 -1
  62. package/build/esm/containers/PageConstructor/components/ConstructorItem/ConstructorItem.js +5 -5
  63. package/build/esm/context/innerContext/InnerContext.d.ts +2 -1
  64. package/build/esm/customization/BlockDecoration.d.ts +3 -0
  65. package/build/esm/customization/BlockDecoration.js +17 -0
  66. package/build/esm/editor/Components/AddBlock/AddBlock.css +82 -0
  67. package/build/esm/editor/Components/AddBlock/AddBlock.d.ts +8 -0
  68. package/build/esm/editor/Components/AddBlock/AddBlock.js +41 -0
  69. package/build/esm/editor/Components/EditBlock/EditBlock.css +47 -0
  70. package/build/esm/editor/Components/EditBlock/EditBlock.d.ts +5 -0
  71. package/build/esm/editor/Components/EditBlock/EditBlock.js +30 -0
  72. package/build/esm/editor/Containers/Editor.d.ts +2 -0
  73. package/build/esm/editor/Containers/Editor.js +20 -0
  74. package/build/esm/editor/data/index.d.ts +13 -0
  75. package/build/esm/editor/data/index.js +24 -0
  76. package/build/esm/editor/data/previews/default-preview.d.ts +3 -0
  77. package/build/esm/editor/data/previews/default-preview.js +15 -0
  78. package/build/esm/editor/data/previews/header-block.d.ts +3 -0
  79. package/build/esm/editor/data/previews/header-block.js +16 -0
  80. package/build/esm/editor/index.d.ts +2 -0
  81. package/build/esm/editor/index.js +2 -0
  82. package/build/esm/editor/store/index.d.ts +15 -0
  83. package/build/esm/editor/store/index.js +28 -0
  84. package/build/esm/editor/store/reducer.d.ts +41 -0
  85. package/build/esm/editor/store/reducer.js +55 -0
  86. package/build/esm/editor/store/utils.d.ts +13 -0
  87. package/build/esm/editor/store/utils.js +26 -0
  88. package/build/esm/editor/styles/mixins.css +0 -0
  89. package/build/esm/editor/styles/variables.css +0 -0
  90. package/build/esm/editor/types/index.d.ts +17 -0
  91. package/build/esm/editor/types/index.js +1 -0
  92. package/build/esm/editor/utils/index.d.ts +11 -0
  93. package/build/esm/editor/utils/index.js +6 -0
  94. package/build/esm/models/constructor-items/blocks.d.ts +1 -11
  95. package/build/esm/models/constructor-items/blocks.js +0 -2
  96. package/build/esm/models/constructor-items/common.d.ts +1 -0
  97. package/build/esm/models/constructor.d.ts +4 -1
  98. package/build/esm/models/customization.d.ts +9 -0
  99. package/build/esm/models/customization.js +1 -0
  100. package/build/esm/models/index.d.ts +1 -0
  101. package/build/esm/models/index.js +1 -0
  102. package/build/esm/utils/blocks.d.ts +4 -1
  103. package/build/esm/utils/blocks.js +7 -0
  104. package/package.json +4 -3
  105. package/server/models/constructor-items/blocks.d.ts +1 -11
  106. package/server/models/constructor-items/blocks.js +0 -2
  107. package/server/models/constructor-items/common.d.ts +1 -0
  108. package/server/models/constructor.d.ts +4 -1
  109. package/server/models/customization.d.ts +9 -0
  110. package/server/models/customization.js +2 -0
  111. package/server/models/index.d.ts +1 -0
  112. package/server/models/index.js +1 -0
  113. package/server/utils/blocks.d.ts +4 -1
  114. package/server/utils/blocks.js +11 -1
@@ -0,0 +1,82 @@
1
+ /* use this for style redefinitions to awoid problems with
2
+ unpredictable css rules order in build */
3
+ .pc-add-block {
4
+ position: fixed;
5
+ bottom: 32px;
6
+ left: 50%;
7
+ transform: translateX(-50%);
8
+ z-index: 110;
9
+ }
10
+ .pc-add-block__button {
11
+ display: inline-block;
12
+ margin: 0;
13
+ padding: 0;
14
+ font: inherit;
15
+ border: none;
16
+ outline: none;
17
+ color: inherit;
18
+ background: none;
19
+ cursor: pointer;
20
+ display: flex;
21
+ justify-content: center;
22
+ align-items: center;
23
+ transition: transform 0.2s;
24
+ width: 76px;
25
+ height: 40px;
26
+ color: var(--yc-color-text-inverted-primary);
27
+ background-color: var(--yc-color-promo-base-neon);
28
+ border-radius: 8px;
29
+ }
30
+ .pc-add-block__button:hover {
31
+ transform: scale(1.05);
32
+ }
33
+ .pc-add-block__icon {
34
+ width: 16px;
35
+ height: 16px;
36
+ }
37
+
38
+ .pc-add-block__popup {
39
+ min-width: 420px;
40
+ border-radius: var(--pc-border-radius);
41
+ box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.06), 0px 4px 24px rgba(0, 0, 0, 0.06);
42
+ }
43
+ .pc-add-block__popup .pc-add-block__search {
44
+ padding: 20px 20px 0;
45
+ }
46
+ .pc-add-block__popup .pc-add-block__blocks {
47
+ display: flex;
48
+ flex-direction: column;
49
+ padding: 20px;
50
+ height: 296px;
51
+ max-height: 296px;
52
+ overflow-y: auto;
53
+ }
54
+ .pc-add-block__popup .pc-add-block__block {
55
+ display: flex;
56
+ justify-content: center;
57
+ align-items: center;
58
+ transition: transform 0.2s;
59
+ margin-top: 20px;
60
+ justify-content: flex-start;
61
+ cursor: pointer;
62
+ }
63
+ .pc-add-block__popup .pc-add-block__block:hover {
64
+ transform: scale(1.05);
65
+ }
66
+ .pc-add-block__popup .pc-add-block__block:first-child {
67
+ margin-top: 0;
68
+ }
69
+ .pc-add-block__popup .pc-add-block__preview {
70
+ width: 148px;
71
+ height: 74px;
72
+ border-radius: var(--pc-border-radius);
73
+ margin-right: 16px;
74
+ }
75
+ .pc-add-block__popup .pc-add-block__title {
76
+ font-size: var(--yc-text-body-2-font-size);
77
+ line-height: var(--yc-text-body-2-line-height);
78
+ }
79
+ .pc-add-block__popup .pc-add-block__title,
80
+ .pc-add-block__popup .pc-add-block__description {
81
+ margin: 0;
82
+ }
@@ -0,0 +1,8 @@
1
+ import { PropsWithChildren } from 'react';
2
+ import { Block } from '../../../models';
3
+ import './AddBlock.css';
4
+ export interface AddBlockProps {
5
+ onAdd: (data: Block) => void;
6
+ }
7
+ declare const AddBlock: ({ onAdd }: PropsWithChildren<AddBlockProps>) => JSX.Element;
8
+ export default AddBlock;
@@ -0,0 +1,41 @@
1
+ import React, { useMemo, useRef, useState } from 'react';
2
+ import { Plus } from '@gravity-ui/icons';
3
+ import { Popup, TextInput } from '@gravity-ui/uikit';
4
+ import { blockMap } from '../../../constructor-items';
5
+ import { block } from '../../../utils';
6
+ import EditorBlocksData from '../../data';
7
+ import './AddBlock.css';
8
+ const b = block('add-block');
9
+ const sortedBlockNames = Object.keys(blockMap).sort();
10
+ const AddBlock = ({ onAdd }) => {
11
+ const [isOpened, setIsOpened] = useState(false);
12
+ const [search, setSearch] = useState('');
13
+ const ref = useRef(null);
14
+ const blocks = useMemo(() => sortedBlockNames.filter((blockName) => EditorBlocksData[blockName].meta.title
15
+ .toLocaleLowerCase()
16
+ .startsWith(search.toLocaleLowerCase())), [search]);
17
+ return (React.createElement("div", { className: b(), ref: ref },
18
+ React.createElement("button", { className: b('button'), onClick: () => {
19
+ setIsOpened(!isOpened);
20
+ setSearch('');
21
+ } },
22
+ React.createElement(Plus, { className: b('icon') })),
23
+ isOpened && (React.createElement(Popup, { anchorRef: ref, open: isOpened, className: b('popup'), placement: "top", offset: [0, 24], onOutsideClick: () => setIsOpened(false) },
24
+ React.createElement("div", { className: b('search') },
25
+ React.createElement(TextInput, { placeholder: "search", type: "text", value: search, size: "l", onUpdate: (value) => setSearch(value) })),
26
+ React.createElement("div", { className: b('blocks') }, blocks.map((blockName) => {
27
+ var _a;
28
+ const blockData = EditorBlocksData[blockName];
29
+ const Preview = blockData === null || blockData === void 0 ? void 0 : blockData.preview;
30
+ return (React.createElement("div", { key: blockName, className: b('block'), onClick: () => {
31
+ onAdd(blockData === null || blockData === void 0 ? void 0 : blockData.template);
32
+ setIsOpened(false);
33
+ } },
34
+ React.createElement("div", { className: b('preview') },
35
+ React.createElement(Preview, null)),
36
+ React.createElement("div", { className: b('info') },
37
+ React.createElement("h4", { className: b('title') }, blockData.meta.title),
38
+ ((_a = blockData === null || blockData === void 0 ? void 0 : blockData.meta) === null || _a === void 0 ? void 0 : _a.description) && (React.createElement("p", { className: b('description') }, blockData.meta.description)))));
39
+ }))))));
40
+ };
41
+ export default AddBlock;
@@ -0,0 +1,47 @@
1
+ /* use this for style redefinitions to awoid problems with
2
+ unpredictable css rules order in build */
3
+ .pc-edit-block {
4
+ cursor: pointer;
5
+ position: relative;
6
+ }
7
+ .pc-edit-block__controls {
8
+ position: absolute;
9
+ width: calc(100% + 40px);
10
+ height: calc(100% + 40px);
11
+ top: -20px;
12
+ left: -20px;
13
+ border-radius: 8px;
14
+ z-index: 100;
15
+ }
16
+ .pc-edit-block__controls_isHeader {
17
+ width: 100%;
18
+ height: 100%;
19
+ top: 0;
20
+ left: 0;
21
+ }
22
+ .pc-edit-block__controls_active {
23
+ border: 4px solid var(--yc-color-promo-base-neon);
24
+ }
25
+ .pc-edit-block__controls-content {
26
+ display: flex;
27
+ position: absolute;
28
+ bottom: -44px;
29
+ left: 50%;
30
+ transform: translateX(-50%);
31
+ }
32
+ .pc-edit-block__control {
33
+ display: flex;
34
+ justify-content: center;
35
+ align-items: center;
36
+ transition: transform 0.2s;
37
+ width: 24px;
38
+ height: 24px;
39
+ border-radius: calc(8px / 2);
40
+ background-color: var(--yc-color-promo-highlight-neon);
41
+ }
42
+ .pc-edit-block__control:hover {
43
+ transform: scale(1.1);
44
+ }
45
+ .pc-edit-block__control:not(:first-child) {
46
+ margin-left: 12px;
47
+ }
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import { EditBlockProps } from '../../../editor/types';
3
+ import './EditBlock.css';
4
+ declare const _default: React.MemoExoticComponent<({ id, isHeader, activeBlockId, onDelete, onSelect, onCopy, onOrderChange, children, orderedBlocksCount, }: EditBlockProps) => JSX.Element>;
5
+ export default _default;
@@ -0,0 +1,30 @@
1
+ import React, { Fragment, useEffect, useRef } from 'react';
2
+ import { ChevronDown, ChevronUp, Copy, TrashBin } from '@gravity-ui/icons';
3
+ import { block } from '../../../utils';
4
+ import './EditBlock.css';
5
+ const b = block('edit-block');
6
+ const EditBlock = ({ id, isHeader, activeBlockId, onDelete, onSelect, onCopy, onOrderChange, children, orderedBlocksCount, }) => {
7
+ const ref = useRef(null);
8
+ const controlsActive = activeBlockId === id;
9
+ useEffect(() => {
10
+ var _a;
11
+ if (controlsActive && ref.current) {
12
+ (_a = ref.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ behavior: 'smooth', block: 'center' });
13
+ }
14
+ }, [controlsActive]);
15
+ return (React.createElement("div", { className: b(), onClick: () => {
16
+ onSelect(id);
17
+ }, ref: ref },
18
+ React.createElement("div", { className: b('controls', { active: controlsActive, isHeader }) }, controlsActive && (React.createElement("div", { className: b('controls-content'), onClick: (e) => e.stopPropagation() },
19
+ typeof id === 'number' && (React.createElement(Fragment, null,
20
+ id > 0 && (React.createElement("div", { className: b('control'), onClick: () => onOrderChange(id, id - 1) },
21
+ React.createElement(ChevronUp, null))),
22
+ id < orderedBlocksCount - 1 && (React.createElement("div", { className: b('control'), onClick: () => onOrderChange(id, id + 1) },
23
+ React.createElement(ChevronDown, null))),
24
+ React.createElement("div", { className: b('control'), onClick: () => onCopy(id) },
25
+ React.createElement(Copy, null)))),
26
+ React.createElement("div", { className: b('control'), onClick: () => onDelete(id) },
27
+ React.createElement(TrashBin, null))))),
28
+ children));
29
+ };
30
+ export default React.memo(EditBlock);
@@ -0,0 +1,2 @@
1
+ import { EditorProps } from '../types';
2
+ export declare const Editor: ({ children, ...rest }: EditorProps) => JSX.Element;
@@ -0,0 +1,20 @@
1
+ import { __rest } from "tslib";
2
+ import React, { useMemo } from 'react';
3
+ import AddBlock from '../Components/AddBlock/AddBlock';
4
+ import EditBlock from '../Components/EditBlock/EditBlock';
5
+ import { useEditorState } from '../store';
6
+ import { addCustomDecorator } from '../utils';
7
+ export const Editor = (_a) => {
8
+ var { children } = _a, rest = __rest(_a, ["children"]);
9
+ const { content, onAdd, editControlsProps } = useEditorState(rest);
10
+ const constructorProps = useMemo(() => {
11
+ const editControlsDecorator = (props) => (React.createElement(EditBlock, Object.assign({}, props, editControlsProps)));
12
+ return {
13
+ content,
14
+ custom: addCustomDecorator(editControlsDecorator, rest.custom),
15
+ };
16
+ }, [editControlsProps, content, rest.custom]);
17
+ return (React.createElement("div", null,
18
+ children(constructorProps),
19
+ React.createElement(AddBlock, { onAdd: onAdd })));
20
+ };
@@ -0,0 +1,13 @@
1
+ /// <reference types="react" />
2
+ import { Block, BlockType } from '../../models';
3
+ export type PreviewComponent = React.FunctionComponent<React.SVGProps<SVGSVGElement>>;
4
+ export interface EdiorBlockData {
5
+ template: Block;
6
+ preview: PreviewComponent;
7
+ meta: {
8
+ title: string;
9
+ description?: string;
10
+ };
11
+ }
12
+ declare const EditorBlocksData: Record<BlockType, EdiorBlockData>;
13
+ export default EditorBlocksData;
@@ -0,0 +1,24 @@
1
+ import { BlockType } from '../../models';
2
+ import { formatBlockName } from '../utils';
3
+ import DefaultPreview from './previews/default-preview';
4
+ const getBlockTemplate = (blockType) => require(`./templates/${blockType}.json`);
5
+ const getBlockPreview = (blockType) => {
6
+ try {
7
+ return require(`./previews/${blockType}.tsx`).default;
8
+ }
9
+ catch (err) {
10
+ /*eslint-disable no-console */
11
+ console.warn(`Preview image for ${blockType} not found`);
12
+ return DefaultPreview;
13
+ }
14
+ };
15
+ const EditorBlocksData = Object.values(BlockType).reduce((previewData, blockType) => {
16
+ const template = getBlockTemplate(blockType);
17
+ const preview = getBlockPreview(blockType);
18
+ template.meta = template.meta || {};
19
+ template.meta.title = template.meta.title || formatBlockName(blockType);
20
+ /* eslint-disable no-param-reassign */
21
+ previewData[blockType] = Object.assign(Object.assign({}, template), { preview });
22
+ return previewData;
23
+ }, {});
24
+ export default EditorBlocksData;
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ declare const DefaultPreview: React.FC<React.SVGProps<SVGSVGElement>>;
3
+ export default DefaultPreview;
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import { a11yHiddenSvgProps } from '../../../utils/svg';
3
+ const DefaultPreview = (props) => (React.createElement("svg", Object.assign({ width: "150", height: "76", viewBox: "0 0 150 76", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, a11yHiddenSvgProps, props),
4
+ React.createElement("rect", { x: "1", y: "1", width: "148", height: "74", rx: "8", fill: "white" }),
5
+ React.createElement("rect", { x: "14.7674", y: "21.6512", width: "28.3953", height: "6.88372", rx: "0.860465", fill: "#E7E7E7" }),
6
+ React.createElement("rect", { x: "43.1628", y: "21.6512", width: "28.3953", height: "6.88372", rx: "0.860465", fill: "white" }),
7
+ React.createElement("rect", { x: "14.7674", y: "31.9767", width: "56.7907", height: "3.44186", rx: "0.860465", fill: "#E7E7E7" }),
8
+ React.createElement("rect", { x: "14.7675", y: "37.1395", width: "56.7907", height: "3.44186", rx: "0.860465", fill: "#E7E7E7" }),
9
+ React.createElement("rect", { x: "14.7675", y: "42.3023", width: "56.7907", height: "3.44186", rx: "0.860465", fill: "#E7E7E7" }),
10
+ React.createElement("rect", { x: "14.7674", y: "49.186", width: "18.9302", height: "5.16279", rx: "0.860465", fill: "#E7E7E7" }),
11
+ React.createElement("rect", { x: "33.6977", y: "49.186", width: "18.9302", height: "5.16279", rx: "0.860465", fill: "white" }),
12
+ React.createElement("rect", { x: "52.6279", y: "49.186", width: "18.9302", height: "5.16279", rx: "0.860465", fill: "white" }),
13
+ React.createElement("rect", { x: "78.4418", y: "9.60464", width: "56.7907", height: "56.7907", rx: "5.16279", fill: "#A967FF" }),
14
+ React.createElement("rect", { x: "0.5", y: "0.5", width: "149", height: "75", rx: "8.5", stroke: "black", strokeOpacity: "0.1" })));
15
+ export default DefaultPreview;
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ declare const Header: React.FC<React.SVGProps<SVGSVGElement>>;
3
+ export default Header;
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import { a11yHiddenSvgProps } from '../../../utils/svg';
3
+ const Header = (props) => (React.createElement("svg", Object.assign({ width: "150", height: "76", viewBox: "0 0 150 76", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, a11yHiddenSvgProps, props),
4
+ React.createElement("rect", { x: "1", y: "1", width: "148", height: "74", rx: "8", fill: "white" }),
5
+ React.createElement("rect", { x: "4.44174", y: "9.60464", width: "141.116", height: "56.7907", rx: "5.16279", fill: "#A967FF" }),
6
+ React.createElement("rect", { x: "14.7674", y: "21.6512", width: "28.3953", height: "6.88372", rx: "0.860465", fill: "white" }),
7
+ React.createElement("rect", { x: "43.1628", y: "21.6512", width: "28.3953", height: "6.88372", rx: "0.860465", fill: "#A967FF" }),
8
+ React.createElement("rect", { x: "14.7674", y: "31.9767", width: "56.7907", height: "3.44186", rx: "0.860465", fill: "white" }),
9
+ React.createElement("rect", { x: "14.7674", y: "37.1395", width: "56.7907", height: "3.44186", rx: "0.860465", fill: "white" }),
10
+ React.createElement("rect", { x: "14.7674", y: "42.3023", width: "56.7907", height: "3.44186", rx: "0.860465", fill: "white" }),
11
+ React.createElement("rect", { x: "14.7674", y: "49.186", width: "18.9302", height: "5.16279", rx: "0.860465", fill: "white" }),
12
+ React.createElement("rect", { x: "33.6976", y: "49.186", width: "18.9302", height: "5.16279", rx: "0.860465", fill: "#A967FF" }),
13
+ React.createElement("rect", { x: "52.6279", y: "49.186", width: "18.9302", height: "5.16279", rx: "0.860465", fill: "#A967FF" }),
14
+ React.createElement("rect", { x: "78.4418", y: "9.60464", width: "56.7907", height: "56.7907", rx: "5.16279", fill: "#A967FF" }),
15
+ React.createElement("rect", { x: "0.5", y: "0.5", width: "149", height: "75", rx: "8.5", stroke: "black", strokeOpacity: "0.1" })));
16
+ export default Header;
@@ -0,0 +1,2 @@
1
+ export { Editor } from './Containers/Editor';
2
+ export * from './types';
@@ -0,0 +1,2 @@
1
+ export { Editor } from './Containers/Editor';
2
+ export * from './types';
@@ -0,0 +1,15 @@
1
+ import { Block } from '../../models';
2
+ import { EditorProps } from '../types';
3
+ export type EditorBlockId = number | string;
4
+ export declare function useEditorState({ content: intialContent, custom }: Omit<EditorProps, 'children'>): {
5
+ content: import("../../models").PageContent;
6
+ editControlsProps: {
7
+ activeBlockId: import("./reducer").EditorBlockId;
8
+ orderedBlocksCount: number;
9
+ onDelete: (id: EditorBlockId) => void;
10
+ onSelect: (id: EditorBlockId) => void;
11
+ onCopy: (index: number) => void;
12
+ onOrderChange: (oldIndex: number, newIndex: number) => void;
13
+ };
14
+ onAdd: (block: Block) => void;
15
+ };
@@ -0,0 +1,28 @@
1
+ import { useMemo, useReducer } from 'react';
2
+ import { HeaderBlockTypes } from '../../models';
3
+ import { getCustomHeaderTypes, getOrderedBlocks } from '../../utils';
4
+ import { ADD_BLOCK, COPY_BLOCK, DELETE_BLOCK, ORDER_BLOCK, SELECT_BLOCK, getReducer, } from './reducer';
5
+ import { addEditorProps } from './utils';
6
+ export function useEditorState({ content: intialContent, custom }) {
7
+ const headerBlockTypes = useMemo(() => [...HeaderBlockTypes, ...getCustomHeaderTypes(custom)], [custom]);
8
+ const reducer = useMemo(() => getReducer(headerBlockTypes), [headerBlockTypes]);
9
+ const [{ activeBlockId, content, orderedBlocksCount }, dispatch] = useReducer(reducer, {
10
+ activeBlockId: 0,
11
+ orderedBlocksCount: getOrderedBlocks(intialContent.blocks, headerBlockTypes).length,
12
+ content: addEditorProps(intialContent),
13
+ });
14
+ return useMemo(() => {
15
+ return {
16
+ content,
17
+ editControlsProps: {
18
+ activeBlockId,
19
+ orderedBlocksCount,
20
+ onDelete: (id) => dispatch({ type: DELETE_BLOCK, payload: id }),
21
+ onSelect: (id) => dispatch({ type: SELECT_BLOCK, payload: id }),
22
+ onCopy: (index) => dispatch({ type: COPY_BLOCK, payload: index }),
23
+ onOrderChange: (oldIndex, newIndex) => dispatch({ type: ORDER_BLOCK, payload: { oldIndex, newIndex } }),
24
+ },
25
+ onAdd: (block) => dispatch({ type: ADD_BLOCK, payload: block }),
26
+ };
27
+ }, [content, activeBlockId, orderedBlocksCount]);
28
+ }
@@ -0,0 +1,41 @@
1
+ import { Block, CustomConfig, PageContent } from '../../models';
2
+ export type EditorBlockId = number | string;
3
+ interface EditorState {
4
+ content: PageContent;
5
+ activeBlockId: EditorBlockId;
6
+ orderedBlocksCount: number;
7
+ custom?: CustomConfig;
8
+ }
9
+ interface OrderBlockParams {
10
+ oldIndex: number;
11
+ newIndex: number;
12
+ }
13
+ export declare const SELECT_BLOCK = "SELECT_BLOCK";
14
+ export declare const DELETE_BLOCK = "DELETE_BLOCK";
15
+ export declare const COPY_BLOCK = "COPY_BLOCK";
16
+ export declare const ADD_BLOCK = "ADD_BLOCK";
17
+ export declare const SET_REGION = "SET_REGION";
18
+ export declare const ORDER_BLOCK = "ORDER_BLOCK";
19
+ interface SelectBlock {
20
+ type: typeof SELECT_BLOCK;
21
+ payload: EditorBlockId;
22
+ }
23
+ interface DeleteBlock {
24
+ type: typeof DELETE_BLOCK;
25
+ payload: EditorBlockId;
26
+ }
27
+ interface CopyBlock {
28
+ type: typeof COPY_BLOCK;
29
+ payload: number;
30
+ }
31
+ interface AddBlock {
32
+ type: typeof ADD_BLOCK;
33
+ payload: Block;
34
+ }
35
+ interface OrderBlock {
36
+ type: typeof ORDER_BLOCK;
37
+ payload: OrderBlockParams;
38
+ }
39
+ export type EditorAction = SelectBlock | DeleteBlock | CopyBlock | AddBlock | OrderBlock;
40
+ export declare const getReducer: (headerBlockTypes: string[]) => (state: EditorState, action: EditorAction) => EditorState;
41
+ export {};
@@ -0,0 +1,55 @@
1
+ import { getHeaderBlock, getOrderedBlocks } from '../../utils';
2
+ import { addBlock, changeBlocksOrder, duplicateBlock, getNewBlockIndex } from './utils';
3
+ // actions
4
+ export const SELECT_BLOCK = 'SELECT_BLOCK';
5
+ export const DELETE_BLOCK = 'DELETE_BLOCK';
6
+ export const COPY_BLOCK = 'COPY_BLOCK';
7
+ export const ADD_BLOCK = 'ADD_BLOCK';
8
+ export const SET_REGION = 'SET_REGION';
9
+ export const ORDER_BLOCK = 'ORDER_BLOCK';
10
+ // reducer
11
+ export const getReducer = (headerBlockTypes) => (state, action) => {
12
+ const { content } = state;
13
+ const header = getHeaderBlock(content.blocks, headerBlockTypes);
14
+ const orderedBlocks = getOrderedBlocks(content.blocks, headerBlockTypes);
15
+ const withHeader = (blocks) => [header, ...blocks].filter(Boolean);
16
+ const getNewState = (blocks, activeBlockId) => (Object.assign(Object.assign({}, state), { content: Object.assign(Object.assign({}, content), { blocks }), activeBlockId, orderedBlocksCount: orderedBlocks.length }));
17
+ switch (action.type) {
18
+ case SELECT_BLOCK:
19
+ return getNewState(content.blocks, action.payload);
20
+ case DELETE_BLOCK: {
21
+ const blockId = action.payload;
22
+ return getNewState(typeof blockId === 'string'
23
+ ? content.blocks.filter(({ type }) => type !== blockId)
24
+ : withHeader(orderedBlocks.filter((_block, index) => index !== blockId)), -1);
25
+ }
26
+ case COPY_BLOCK: {
27
+ const index = action.payload;
28
+ return getNewState(withHeader(duplicateBlock(orderedBlocks, index)), index + 1);
29
+ }
30
+ case ADD_BLOCK: {
31
+ let blocks;
32
+ let activeBlockId;
33
+ const block = action.payload;
34
+ if (headerBlockTypes.includes(block.type)) {
35
+ blocks = header ? blocks : [block, ...orderedBlocks];
36
+ activeBlockId = block.type;
37
+ }
38
+ else {
39
+ const newBlockIndex = getNewBlockIndex(state.activeBlockId, orderedBlocks.length);
40
+ blocks = withHeader(addBlock(orderedBlocks, block, newBlockIndex));
41
+ activeBlockId = newBlockIndex;
42
+ }
43
+ if (blocks) {
44
+ return getNewState(blocks, activeBlockId);
45
+ }
46
+ return state;
47
+ }
48
+ case ORDER_BLOCK: {
49
+ const { oldIndex, newIndex } = action.payload;
50
+ return getNewState(withHeader(changeBlocksOrder(orderedBlocks, oldIndex, newIndex)), newIndex);
51
+ }
52
+ default:
53
+ return state;
54
+ }
55
+ };
@@ -0,0 +1,13 @@
1
+ import { Block, PageContent } from '../../models';
2
+ import { EditorBlockId } from './reducer';
3
+ export declare const changeBlocksOrder: (array: Block[], oldIndex: number, newIndex: number) => Block[];
4
+ export declare const duplicateBlock: (array: Block[], index: number) => Block[];
5
+ export declare const getNewBlockIndex: (id: EditorBlockId, orderedBlocksCount: number) => number;
6
+ export declare const addBlock: (array: Block[], block: Block, index: number) => Block[];
7
+ export declare const addEditorProps: (content: PageContent) => {
8
+ animated: boolean;
9
+ blocks: Block[];
10
+ menu?: import("../../models").Menu | undefined;
11
+ background?: import("../../models").ThemedMediaProps | undefined;
12
+ footnotes?: string[] | undefined;
13
+ };
@@ -0,0 +1,26 @@
1
+ export const changeBlocksOrder = (array, oldIndex, newIndex) => {
2
+ const result = [...array];
3
+ const element = result.splice(oldIndex, 1)[0];
4
+ result.splice(newIndex, 0, element);
5
+ return result;
6
+ };
7
+ export const duplicateBlock = (array, index) => {
8
+ const result = [...array];
9
+ result.splice(index + 1, 0, result[index]);
10
+ return result;
11
+ };
12
+ export const getNewBlockIndex = (id, orderedBlocksCount) => {
13
+ if (id === -1) {
14
+ return orderedBlocksCount;
15
+ }
16
+ // id === 'string' - header block
17
+ return typeof id === 'string' ? 0 : id + 1;
18
+ };
19
+ export const addBlock = (array, block, index) => {
20
+ const result = [...array];
21
+ result.splice(index, 0, block);
22
+ return result;
23
+ };
24
+ export const addEditorProps = (content) => {
25
+ return Object.assign(Object.assign({}, content), { animated: false });
26
+ };
File without changes
File without changes
@@ -0,0 +1,17 @@
1
+ /// <reference types="react" />
2
+ import { PageConstructorProps } from '../../containers/PageConstructor';
3
+ import { BlockDecoratorProps, PageData } from '../../models';
4
+ export type EditorBlockId = number | string;
5
+ export interface EditorProps extends Required<Pick<PageConstructorProps, 'content'>>, Partial<Omit<PageConstructorProps, 'content'>> {
6
+ children: (props: Partial<PageConstructorProps>) => React.ReactNode;
7
+ onChange?: (data: PageData) => void;
8
+ }
9
+ export interface EditBlockEditorProps {
10
+ activeBlockId: EditorBlockId;
11
+ orderedBlocksCount: number;
12
+ onSelect: (index: EditorBlockId) => void;
13
+ onDelete: (index: EditorBlockId) => void;
14
+ onCopy: (index: number) => void;
15
+ onOrderChange: (index: number, newIndex: number) => void;
16
+ }
17
+ export type EditBlockProps = EditBlockEditorProps & BlockDecoratorProps;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,11 @@
1
+ import { BlockDecorator, CustomConfig } from '../../models';
2
+ export declare const formatBlockName: (name: string) => string;
3
+ export declare const addCustomDecorator: (decorator: BlockDecorator, custom?: CustomConfig) => {
4
+ decorators: {
5
+ block: ((props: import("../../models").BlockDecoratorProps) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>)[];
6
+ };
7
+ blocks?: import("../../models").CustomItems | undefined;
8
+ subBlocks?: import("../../models").CustomItems | undefined;
9
+ headers?: import("../../models").CustomItems | undefined;
10
+ loadable?: import("../../models").LoadableConfig | undefined;
11
+ };
@@ -0,0 +1,6 @@
1
+ import _ from 'lodash';
2
+ export const formatBlockName = (name) => _.capitalize(name).replace(/(block|-)/g, ' ');
3
+ export const addCustomDecorator = (decorator, custom = {}) => {
4
+ const decorators = custom.decorators || {};
5
+ return Object.assign(Object.assign({}, custom), { decorators: Object.assign(Object.assign({}, decorators), { block: [...(decorators.block || []), decorator] }) });
6
+ };
@@ -8,8 +8,6 @@ export declare enum BlockType {
8
8
  PromoFeaturesBlock = "promo-features-block",
9
9
  ExtendedFeaturesBlock = "extended-features-block",
10
10
  SliderBlock = "slider-block",
11
- CalculatorBlock = "calculator-block",
12
- ServiceDemoBlock = "service-demo-block",
13
11
  QuestionsBlock = "questions-block",
14
12
  BannerBlock = "banner-block",
15
13
  CompaniesBlock = "companies-block",
@@ -52,7 +50,6 @@ export interface LoadableProps {
52
50
  export interface LoadableChildren {
53
51
  loadable?: LoadableProps;
54
52
  }
55
- export type ServiceDemoProps = Animatable;
56
53
  export declare enum SliderBreakpointNames {
57
54
  Sm = "sm",
58
55
  Md = "md",
@@ -114,7 +111,6 @@ export interface HeaderBlockProps {
114
111
  breadcrumbs?: HeaderBreadCrumbsProps;
115
112
  status?: JSX.Element;
116
113
  }
117
- export type CalculatorProps = Animatable;
118
114
  export interface SimpleBlockProps extends Animatable, Childable {
119
115
  title: TitleBaseProps;
120
116
  description: string;
@@ -317,15 +313,9 @@ export interface ShareBlockProps {
317
313
  export type HeaderBlockModel = {
318
314
  type: BlockType.HeaderBlock;
319
315
  } & HeaderBlockProps;
320
- export type CalculatorBlockModel = {
321
- type: BlockType.CalculatorBlock;
322
- } & CalculatorProps;
323
316
  export type SliderBlockModel = {
324
317
  type: BlockType.SliderBlock;
325
318
  } & SliderProps;
326
- export type ServiceDemoBlockModel = {
327
- type: BlockType.ServiceDemoBlock;
328
- } & ServiceDemoProps;
329
319
  export type ExtendedFeaturesBlockModel = {
330
320
  type: BlockType.ExtendedFeaturesBlock;
331
321
  } & ExtendedFeaturesProps;
@@ -386,6 +376,6 @@ export type ContentLayoutBlockModel = {
386
376
  export type ShareBLockModel = {
387
377
  type: BlockType.ShareBlock;
388
378
  } & ShareBlockProps;
389
- type BlockModels = SliderBlockModel | ServiceDemoBlockModel | ExtendedFeaturesBlockModel | PromoFeaturesBlockModel | QuestionsBlockModel | CalculatorBlockModel | BannerBlockModel | CompaniesBlockModel | MediaBlockModel | MapBlockModel | InfoBlockModel | SecurityBlockModel | TableBlockModel | TabsBlockModel | SimpleBlockModel | LinkTableBlockModel | HeaderBlockModel | PreviewBlockModel | IconsBlockModel | HeaderSliderBlockModel | CardLayoutBlockModel | ContentLayoutBlockModel | ShareBLockModel | FilterBlockModel;
379
+ type BlockModels = SliderBlockModel | ExtendedFeaturesBlockModel | PromoFeaturesBlockModel | QuestionsBlockModel | BannerBlockModel | CompaniesBlockModel | MediaBlockModel | MapBlockModel | InfoBlockModel | SecurityBlockModel | TableBlockModel | TabsBlockModel | SimpleBlockModel | LinkTableBlockModel | HeaderBlockModel | PreviewBlockModel | IconsBlockModel | HeaderSliderBlockModel | CardLayoutBlockModel | ContentLayoutBlockModel | ShareBLockModel | FilterBlockModel;
390
380
  export type Block = BlockModels & BlockBaseProps;
391
381
  export {};
@@ -3,8 +3,6 @@ export var BlockType;
3
3
  BlockType["PromoFeaturesBlock"] = "promo-features-block";
4
4
  BlockType["ExtendedFeaturesBlock"] = "extended-features-block";
5
5
  BlockType["SliderBlock"] = "slider-block";
6
- BlockType["CalculatorBlock"] = "calculator-block";
7
- BlockType["ServiceDemoBlock"] = "service-demo-block";
8
6
  BlockType["QuestionsBlock"] = "questions-block";
9
7
  BlockType["BannerBlock"] = "banner-block";
10
8
  BlockType["CompaniesBlock"] = "companies-block";
@@ -99,6 +99,7 @@ export interface BackgroundImageProps extends React.HTMLProps<HTMLDivElement>, P
99
99
  style?: CSSProperties;
100
100
  imageClassName?: string;
101
101
  hide?: boolean;
102
+ qa?: string;
102
103
  }
103
104
  export interface MediaVideoProps extends AnalyticsEventsBase {
104
105
  src: string[];