@gravity-ui/page-constructor 4.41.1-alpha.0 → 4.42.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 (76) hide show
  1. package/build/cjs/blocks/CardLayout/schema.d.ts +24 -0
  2. package/build/cjs/blocks/ContentLayout/schema.d.ts +12 -0
  3. package/build/cjs/blocks/ExtendedFeatures/schema.d.ts +12 -0
  4. package/build/cjs/blocks/FilterBlock/schema.d.ts +24 -0
  5. package/build/cjs/blocks/Form/schema.d.ts +12 -0
  6. package/build/cjs/blocks/Header/schema.d.ts +12 -0
  7. package/build/cjs/blocks/HeaderSlider/schema.d.ts +12 -0
  8. package/build/cjs/blocks/Icons/schema.d.ts +24 -0
  9. package/build/cjs/blocks/Map/schema.d.ts +12 -0
  10. package/build/cjs/blocks/Media/schema.d.ts +24 -0
  11. package/build/cjs/blocks/PromoFeaturesBlock/schema.d.ts +12 -0
  12. package/build/cjs/blocks/Questions/schema.d.ts +12 -0
  13. package/build/cjs/blocks/Slider/schema.d.ts +12 -0
  14. package/build/cjs/blocks/Table/schema.d.ts +12 -0
  15. package/build/cjs/blocks/Tabs/schema.d.ts +12 -0
  16. package/build/cjs/components/ContentList/ContentList.css +16 -16
  17. package/build/cjs/components/ContentList/ContentList.js +2 -2
  18. package/build/cjs/constructor-items.d.ts +1 -0
  19. package/build/cjs/constructor-items.js +1 -0
  20. package/build/cjs/editor/components/CodeEditor/CodeEditor.css +2 -5
  21. package/build/cjs/editor/components/CodeEditor/CodeEditor.d.ts +2 -2
  22. package/build/cjs/editor/components/CodeEditor/CodeEditor.js +12 -9
  23. package/build/cjs/editor/containers/Editor/Editor.d.ts +1 -1
  24. package/build/cjs/editor/containers/Editor/Editor.js +19 -8
  25. package/build/cjs/editor/containers/Form/Form.js +3 -1
  26. package/build/cjs/editor/containers/Form/hooks.d.ts +8 -0
  27. package/build/cjs/editor/containers/Form/hooks.js +39 -0
  28. package/build/cjs/editor/context.d.ts +2 -0
  29. package/build/cjs/editor/types/index.d.ts +2 -0
  30. package/build/cjs/navigation/components/NavigationItem/NavigationItem.js +6 -3
  31. package/build/cjs/schema/validators/common.d.ts +13 -1
  32. package/build/cjs/schema/validators/common.js +8 -1
  33. package/build/cjs/sub-blocks/Content/Content.css +6 -0
  34. package/build/cjs/sub-blocks/Content/Content.js +2 -1
  35. package/build/cjs/sub-blocks/Divider/schema.d.ts +1 -1
  36. package/build/cjs/sub-blocks/PriceCard/PriceCard.css +23 -2
  37. package/build/cjs/sub-blocks/PriceCard/PriceCard.js +3 -3
  38. package/build/esm/blocks/CardLayout/schema.d.ts +24 -0
  39. package/build/esm/blocks/ContentLayout/schema.d.ts +12 -0
  40. package/build/esm/blocks/ExtendedFeatures/schema.d.ts +12 -0
  41. package/build/esm/blocks/FilterBlock/schema.d.ts +24 -0
  42. package/build/esm/blocks/Form/schema.d.ts +12 -0
  43. package/build/esm/blocks/Header/schema.d.ts +12 -0
  44. package/build/esm/blocks/HeaderSlider/schema.d.ts +12 -0
  45. package/build/esm/blocks/Icons/schema.d.ts +24 -0
  46. package/build/esm/blocks/Map/schema.d.ts +12 -0
  47. package/build/esm/blocks/Media/schema.d.ts +24 -0
  48. package/build/esm/blocks/PromoFeaturesBlock/schema.d.ts +12 -0
  49. package/build/esm/blocks/Questions/schema.d.ts +12 -0
  50. package/build/esm/blocks/Slider/schema.d.ts +12 -0
  51. package/build/esm/blocks/Table/schema.d.ts +12 -0
  52. package/build/esm/blocks/Tabs/schema.d.ts +12 -0
  53. package/build/esm/components/ContentList/ContentList.css +16 -16
  54. package/build/esm/components/ContentList/ContentList.js +2 -2
  55. package/build/esm/constructor-items.d.ts +1 -0
  56. package/build/esm/constructor-items.js +2 -1
  57. package/build/esm/editor/components/CodeEditor/CodeEditor.css +2 -5
  58. package/build/esm/editor/components/CodeEditor/CodeEditor.d.ts +2 -2
  59. package/build/esm/editor/components/CodeEditor/CodeEditor.js +13 -10
  60. package/build/esm/editor/containers/Editor/Editor.d.ts +1 -1
  61. package/build/esm/editor/containers/Editor/Editor.js +19 -8
  62. package/build/esm/editor/containers/Form/Form.js +3 -1
  63. package/build/esm/editor/containers/Form/hooks.d.ts +8 -0
  64. package/build/esm/editor/containers/Form/hooks.js +34 -0
  65. package/build/esm/editor/context.d.ts +2 -0
  66. package/build/esm/editor/types/index.d.ts +2 -0
  67. package/build/esm/navigation/components/NavigationItem/NavigationItem.js +7 -4
  68. package/build/esm/schema/validators/common.d.ts +13 -1
  69. package/build/esm/schema/validators/common.js +8 -1
  70. package/build/esm/sub-blocks/Content/Content.css +6 -0
  71. package/build/esm/sub-blocks/Content/Content.js +2 -1
  72. package/build/esm/sub-blocks/Divider/schema.d.ts +1 -1
  73. package/build/esm/sub-blocks/PriceCard/PriceCard.css +23 -2
  74. package/build/esm/sub-blocks/PriceCard/PriceCard.js +3 -3
  75. package/package.json +1 -1
  76. package/widget/index.js +1 -1
@@ -1,8 +1,5 @@
1
1
  /* use this for style redefinitions to awoid problems with
2
2
  unpredictable css rules order in build */
3
- .pc-content-list_size_l {
4
- margin-top: 24px;
5
- }
6
3
  .pc-content-list_size_l .pc-content-list__title {
7
4
  font-size: var(--g-text-header-1-font-size);
8
5
  line-height: var(--g-text-header-1-line-height);
@@ -15,19 +12,19 @@ unpredictable css rules order in build */
15
12
  margin-bottom: 1px;
16
13
  margin-right: 12px;
17
14
  }
18
- .pc-content-list_size_l .pc-content-list__icon_without_title {
15
+ .pc-content-list_size_l .pc-content-list__item:not(:last-child) {
16
+ margin-bottom: 16px;
17
+ }
18
+ .pc-content-list_size_l .pc-content-list__item_without-title:not(:last-child) {
19
+ margin-bottom: 12px;
20
+ }
21
+ .pc-content-list_size_l .pc-content-list__item_without-title .pc-content-list__icon {
19
22
  width: 20px;
20
23
  height: 20px;
21
24
  margin-top: 0;
22
25
  margin-bottom: 0;
23
26
  margin-right: 8px;
24
27
  }
25
- .pc-content-list_size_l .pc-content-list__item:not(:last-child) {
26
- margin-bottom: 16px;
27
- }
28
- .pc-content-list_size_s {
29
- margin-top: 16px;
30
- }
31
28
  .pc-content-list_size_s .pc-content-list__title {
32
29
  font-size: var(--g-text-subheader-3-font-size);
33
30
  line-height: var(--g-text-subheader-3-line-height);
@@ -40,12 +37,6 @@ unpredictable css rules order in build */
40
37
  margin-bottom: 2px;
41
38
  margin-right: 8px;
42
39
  }
43
- .pc-content-list_size_s .pc-content-list__icon_without_title {
44
- width: 18px;
45
- height: 18px;
46
- margin-top: 0;
47
- margin-bottom: 0;
48
- }
49
40
  .pc-content-list_size_s .pc-content-list__text {
50
41
  font-size: var(--g-text-body-1-font-size);
51
42
  line-height: var(--g-text-body-1-line-height);
@@ -53,6 +44,15 @@ unpredictable css rules order in build */
53
44
  .pc-content-list_size_s .pc-content-list__item:not(:last-child) {
54
45
  margin-bottom: 12px;
55
46
  }
47
+ .pc-content-list_size_s .pc-content-list__item_without-title:not(:last-child) {
48
+ margin-bottom: 8px;
49
+ }
50
+ .pc-content-list_size_s .pc-content-list__item_without-title .pc-content-list__icon {
51
+ width: 18px;
52
+ height: 18px;
53
+ margin-top: 0;
54
+ margin-bottom: 0;
55
+ }
56
56
  .pc-content-list__icon {
57
57
  display: block;
58
58
  }
@@ -19,8 +19,8 @@ const ContentList = ({ list, size = 'l', qa }) => {
19
19
  const qaAttributes = getQaAttrubutes(qa, ['image', 'title', 'text']);
20
20
  return (React.createElement("div", { className: b({ size }), "data-qa": qa }, list === null || list === void 0 ? void 0 : list.map((item) => {
21
21
  const { icon, title, text } = item;
22
- return (React.createElement("div", { className: b('item'), key: uuidv4() },
23
- React.createElement(ItemIcon, { icon: icon, className: b('icon', { without_title: !title }), qa: qaAttributes.image }),
22
+ return (React.createElement("div", { className: b('item', { 'without-title': !title }), key: uuidv4() },
23
+ React.createElement(ItemIcon, { icon: icon, className: b('icon'), qa: qaAttributes.image }),
24
24
  React.createElement("div", null,
25
25
  title &&
26
26
  React.createElement(getHeadingLevel(size), { className: b('title'), 'data-qa': qaAttributes.title }, React.createElement(YFMWrapper, { content: title, modifiers: { constructor: true } })),
@@ -29,6 +29,7 @@ export declare const subBlockMap: {
29
29
  "basic-card": (props: import("./models").BasicCardProps) => JSX.Element;
30
30
  content: (props: import("./sub-blocks/Content/Content").ContentProps) => JSX.Element;
31
31
  quote: (props: import("./models").QuoteProps) => JSX.Element;
32
+ "price-card": (props: import("./models").PriceCardProps) => JSX.Element;
32
33
  };
33
34
  export declare const navItemMap: {
34
35
  button: import("react").FC<Pick<import("./navigation/models").NavigationItemProps, "className"> & import("./models").ButtonProps>;
@@ -2,7 +2,7 @@ import { BannerBlock, CardLayoutBlock, CompaniesBlock, ContentLayoutBlock, Exten
2
2
  import { BlockType, NavigationItemType, SubBlockType } from './models';
3
3
  import { GithubButton, NavigationButton, NavigationDropdown, NavigationLink, } from './navigation/components/NavigationItem';
4
4
  import SocialIcon from './navigation/components/SocialIcon/SocialIcon';
5
- import { BackgroundCard, BannerCard, BasicCard, Content, Divider, LayoutItem, MediaCard, PriceDetailed, Quote, } from './sub-blocks';
5
+ import { BackgroundCard, BannerCard, BasicCard, Content, Divider, LayoutItem, MediaCard, PriceCard, PriceDetailed, Quote, } from './sub-blocks';
6
6
  export const blockMap = {
7
7
  [BlockType.SliderBlock]: SliderBlock,
8
8
  [BlockType.ExtendedFeaturesBlock]: ExtendedFeaturesBlock,
@@ -34,6 +34,7 @@ export const subBlockMap = {
34
34
  [SubBlockType.BasicCard]: BasicCard,
35
35
  [SubBlockType.Content]: Content,
36
36
  [SubBlockType.Quote]: Quote,
37
+ [SubBlockType.PriceCard]: PriceCard,
37
38
  };
38
39
  export const navItemMap = {
39
40
  [NavigationItemType.Button]: NavigationButton,
@@ -4,17 +4,14 @@
4
4
  overflow: hidden;
5
5
  }
6
6
  .pc-code-editor_fullscreen {
7
- position: fixed;
7
+ position: absolute;
8
8
  top: 0;
9
9
  left: 0;
10
10
  width: 100%;
11
- height: 100vh;
11
+ height: 100%;
12
12
  z-index: 1000;
13
13
  background: var(--g-color-base-background);
14
14
  }
15
- .pc-code-editor_fullscreen .pc-code-editor__header {
16
- margin-top: var(--pc-editor-header-height);
17
- }
18
15
  .pc-code-editor__code {
19
16
  width: 100%;
20
17
  height: 100%;
@@ -2,12 +2,12 @@ import { PageContent } from '../../../models';
2
2
  import { CodeEditorMessageProps } from '../../utils/validation';
3
3
  import './CodeEditor.css';
4
4
  interface CodeEditorProps {
5
- content: PageContent;
5
+ code: string;
6
6
  fullscreenModeOn: boolean;
7
7
  validator: (code: string) => CodeEditorMessageProps;
8
8
  onFullscreenModeOnUpdate: (fullscreenModeOn: boolean) => void;
9
9
  onChange: (content: PageContent) => void;
10
10
  message?: CodeEditorMessageProps;
11
11
  }
12
- export declare const CodeEditor: ({ content, onChange, validator, fullscreenModeOn, onFullscreenModeOnUpdate, }: CodeEditorProps) => JSX.Element;
12
+ export declare const CodeEditor: ({ onChange, validator, fullscreenModeOn, onFullscreenModeOnUpdate, code, }: CodeEditorProps) => JSX.Element;
13
13
  export {};
@@ -1,27 +1,30 @@
1
- import React, { useCallback, useMemo, useState } from 'react';
1
+ import React, { useCallback, useContext, useState } from 'react';
2
2
  import { ChevronsCollapseUpRight, ChevronsExpandUpRight } from '@gravity-ui/icons';
3
3
  import { Button, Icon } from '@gravity-ui/uikit';
4
- import yaml from 'js-yaml';
4
+ import debounce from 'lodash/debounce';
5
5
  import MonacoEditor from 'react-monaco-editor';
6
+ import { Theme } from '../../../models';
6
7
  import { block } from '../../../utils';
8
+ import { EditorContext } from '../../context';
7
9
  import { parseCode } from '../../utils/code';
8
10
  import { options } from './constants';
9
11
  import './CodeEditor.css';
10
12
  const b = block('code-editor');
11
- export const CodeEditor = ({ content, onChange, validator, fullscreenModeOn, onFullscreenModeOnUpdate, }) => {
12
- const value = useMemo(() => yaml.dump(content), [content]);
13
- const [message, setMessage] = useState(() => validator(value));
14
- const onChangeWithValidation = useCallback((code) => {
15
- const validationResult = validator(code);
13
+ export const CodeEditor = ({ onChange, validator, fullscreenModeOn, onFullscreenModeOnUpdate, code, }) => {
14
+ const [message, setMessage] = useState(() => validator(code));
15
+ const { theme = Theme.Light } = useContext(EditorContext);
16
+ // eslint-disable-next-line react-hooks/exhaustive-deps
17
+ const onChangeWithValidation = useCallback(debounce((newCode) => {
18
+ const validationResult = validator(newCode);
16
19
  setMessage(validationResult);
17
- onChange(parseCode(code));
18
- }, [onChange, validator]);
20
+ onChange(parseCode(newCode));
21
+ }, 200), [onChange, validator]);
19
22
  return (React.createElement("div", { className: b({ fullscreen: fullscreenModeOn }) },
20
23
  React.createElement("div", { className: b('header') },
21
24
  React.createElement(Button, { view: "flat-secondary", onClick: () => onFullscreenModeOnUpdate(!fullscreenModeOn) },
22
25
  React.createElement(Icon, { data: fullscreenModeOn ? ChevronsCollapseUpRight : ChevronsExpandUpRight, size: 16 }))),
23
26
  React.createElement("div", { className: b('code') },
24
- React.createElement(MonacoEditor, { key: String(fullscreenModeOn), value: value, language: "yaml", options: options, onChange: onChangeWithValidation, theme: "vs" })),
27
+ React.createElement(MonacoEditor, { key: String(fullscreenModeOn), value: code, language: "yaml", options: options, onChange: onChangeWithValidation, theme: theme === Theme.Dark ? 'vs-dark' : 'vs' })),
25
28
  React.createElement("div", { className: b('footer') }, message && (React.createElement("div", { className: b('message-container') },
26
29
  React.createElement("div", { className: b('message', { status: message.status }) }, message.text))))));
27
30
  };
@@ -1,2 +1,2 @@
1
1
  import { EditorProps } from '../../types';
2
- export declare const Editor: ({ customSchema, onChange, providerProps, transformContent, deviceEmulationSettings, ...rest }: EditorProps) => JSX.Element;
2
+ export declare const Editor: ({ customSchema, onChange, providerProps, transformContent, deviceEmulationSettings, theme: editorTheme, ...rest }: EditorProps) => JSX.Element;
@@ -12,13 +12,15 @@ import { useCodeValidator } from '../../hooks/useCodeValidator';
12
12
  import { useMainState } from '../../store/main';
13
13
  import { useSettingsState } from '../../store/settings';
14
14
  import { ViewModeItem } from '../../types';
15
+ import { FormTab } from '../../types/index';
15
16
  import { addCustomDecorator, checkIsMobile, getBlockId } from '../../utils';
16
17
  import { Form } from '../Form/Form';
17
18
  export const Editor = (_a) => {
18
- var { customSchema, onChange, providerProps, transformContent, deviceEmulationSettings } = _a, rest = __rest(_a, ["customSchema", "onChange", "providerProps", "transformContent", "deviceEmulationSettings"]);
19
+ var { customSchema, onChange, providerProps, transformContent, deviceEmulationSettings, theme: editorTheme } = _a, rest = __rest(_a, ["customSchema", "onChange", "providerProps", "transformContent", "deviceEmulationSettings", "theme"]);
19
20
  const { content, activeBlockIndex, errorBoundaryState, onContentUpdate, onAdd, onSelect, injectEditBlockProps, } = useMainState(rest);
20
- const { viewMode, theme, onViewModeUpdate, onThemeUpdate, formTab, onFormTabUpdate, codeFullscreeModeOn, onCodeFullscreeModeOnUpdate, } = useSettingsState();
21
+ const { viewMode, theme: constructorTheme, onViewModeUpdate, onThemeUpdate, formTab, onFormTabUpdate, codeFullscreeModeOn, onCodeFullscreeModeOnUpdate, } = useSettingsState();
21
22
  const isEditingMode = viewMode === ViewModeItem.Edititng;
23
+ const isCodeOnlyMode = codeFullscreeModeOn && formTab === FormTab.Code && viewMode === ViewModeItem.Edititng;
22
24
  const transformedContent = useMemo(() => (transformContent ? transformContent(content, { viewMode }) : content), [content, transformContent, viewMode]);
23
25
  const schema = useMemo(() => generateDefaultSchema(customSchema), [customSchema]);
24
26
  const codeValidator = useCodeValidator(schema);
@@ -49,19 +51,28 @@ export const Editor = (_a) => {
49
51
  content: transformedContent,
50
52
  custom: rest.custom,
51
53
  },
52
- providerProps: Object.assign(Object.assign({}, providerProps), { isMobile: checkIsMobile(viewMode), theme }),
54
+ providerProps: Object.assign(Object.assign({}, providerProps), { isMobile: checkIsMobile(viewMode), theme: constructorTheme }),
53
55
  deviceEmulationSettings,
54
- }), [providerProps, rest.custom, viewMode, transformedContent, deviceEmulationSettings, theme]);
56
+ theme: editorTheme,
57
+ }), [
58
+ providerProps,
59
+ rest.custom,
60
+ viewMode,
61
+ transformedContent,
62
+ deviceEmulationSettings,
63
+ constructorTheme,
64
+ editorTheme,
65
+ ]);
55
66
  useEffect(() => {
56
67
  onChange === null || onChange === void 0 ? void 0 : onChange(content);
57
68
  }, [content, onChange]);
58
69
  return (React.createElement(EditorContext.Provider, { value: context },
59
- React.createElement(Layout, { mode: viewMode, onModeChange: onViewModeUpdate, theme: theme, onThemeChange: onThemeUpdate },
70
+ React.createElement(Layout, { mode: viewMode, onModeChange: onViewModeUpdate, theme: constructorTheme, onThemeChange: onThemeUpdate },
60
71
  isEditingMode && (React.createElement(Layout.Left, null,
61
72
  React.createElement(Form, { content: content, onChange: onContentUpdate, activeBlockIndex: activeBlockIndex, activeTab: formTab, codeFullscreeModeOn: codeFullscreeModeOn, schema: schema, codeValidator: codeValidator, onActiveTabUpdate: onFormTabUpdate, onCodeFullscreeModeOnUpdate: onCodeFullscreeModeOnUpdate, onSelect: onSelect }))),
62
- React.createElement(Layout.Right, null,
73
+ !isCodeOnlyMode && (React.createElement(Layout.Right, null,
63
74
  React.createElement(ErrorBoundary, { key: errorBoundaryState },
64
- React.createElement(PageConstructorProvider, Object.assign({}, providerProps, { theme: theme }),
75
+ React.createElement(PageConstructorProvider, Object.assign({}, providerProps, { theme: constructorTheme }),
65
76
  React.createElement(PageConstructor, Object.assign({}, outgoingProps)))),
66
- isEditingMode && React.createElement(AddBlock, { onAdd: onAdd })))));
77
+ isEditingMode && React.createElement(AddBlock, { onAdd: onAdd }))))));
67
78
  };
@@ -7,6 +7,7 @@ import { CodeEditor } from '../../components/CodeEditor/CodeEditor';
7
7
  import { PagePropsForm } from '../../components/PagePropsForm/PagePropsForm';
8
8
  import useFormSpec from '../../hooks/useFormSpec';
9
9
  import { FormTab } from '../../types';
10
+ import { useCode } from './hooks';
10
11
  import './Form.css';
11
12
  const b = block('editor-form');
12
13
  const tabsItems = Object.values(FormTab).map((tab) => ({
@@ -15,6 +16,7 @@ const tabsItems = Object.values(FormTab).map((tab) => ({
15
16
  }));
16
17
  export const Form = memo(({ content, onChange, activeBlockIndex, onSelect, schema, codeValidator, activeTab, onActiveTabUpdate, codeFullscreeModeOn, onCodeFullscreeModeOnUpdate, }) => {
17
18
  const _a = content || {}, { blocks } = _a, page = __rest(_a, ["blocks"]);
19
+ const code = useCode({ activeTab, content, codeFullscreeModeOn });
18
20
  const spec = useFormSpec(schema);
19
21
  const { blocks: blocksSpec, page: pageSpec } = spec || {};
20
22
  let form;
@@ -37,7 +39,7 @@ export const Form = memo(({ content, onChange, activeBlockIndex, onSelect, schem
37
39
  break;
38
40
  }
39
41
  case FormTab.Code: {
40
- form = (React.createElement(CodeEditor, { content: content, onChange: onChange, validator: codeValidator, fullscreenModeOn: codeFullscreeModeOn, onFullscreenModeOnUpdate: onCodeFullscreeModeOnUpdate }));
42
+ form = (React.createElement(CodeEditor, { code: code, onChange: onChange, validator: codeValidator, fullscreenModeOn: codeFullscreeModeOn, onFullscreenModeOnUpdate: onCodeFullscreeModeOnUpdate }));
41
43
  break;
42
44
  }
43
45
  }
@@ -0,0 +1,8 @@
1
+ import { FormProps } from './Form';
2
+ /**
3
+ * Transorms PageConstructor content in JSON to YAML on code editor mode switching
4
+ *
5
+ * @param {Object} props - props parent from form
6
+ * @returns {string} - updated code
7
+ */
8
+ export declare function useCode({ activeTab, content, codeFullscreeModeOn, }: Pick<FormProps, 'activeTab' | 'content' | 'codeFullscreeModeOn'>): string;
@@ -0,0 +1,34 @@
1
+ import { useEffect, useState } from 'react';
2
+ import yaml from 'js-yaml';
3
+ import usePreviousValue from '../../hooks/usePreviousValue';
4
+ import { FormTab } from '../../types';
5
+ /**
6
+ * Transorms PageConstructor content in JSON to YAML on code editor mode switching
7
+ *
8
+ * @param {Object} props - props parent from form
9
+ * @returns {string} - updated code
10
+ */
11
+ export function useCode({ activeTab, content, codeFullscreeModeOn, }) {
12
+ var _a;
13
+ const [code, setCode] = useState('');
14
+ const prevTab = usePreviousValue(activeTab);
15
+ const prevContentLength = usePreviousValue((_a = content.blocks) === null || _a === void 0 ? void 0 : _a.length);
16
+ const prevCodeFullscreeModeOn = usePreviousValue(codeFullscreeModeOn);
17
+ useEffect(() => {
18
+ var _a;
19
+ const switchedToCodeEditing = activeTab !== prevTab && activeTab === FormTab.Code;
20
+ const blocksCountChanged = prevContentLength !== ((_a = content.blocks) === null || _a === void 0 ? void 0 : _a.length);
21
+ const codeModeSwitched = codeFullscreeModeOn !== prevCodeFullscreeModeOn;
22
+ if (blocksCountChanged || switchedToCodeEditing || codeModeSwitched) {
23
+ setCode(yaml.dump(content, { lineWidth: -1 }));
24
+ }
25
+ }, [
26
+ activeTab,
27
+ prevTab,
28
+ content,
29
+ prevContentLength,
30
+ codeFullscreeModeOn,
31
+ prevCodeFullscreeModeOn,
32
+ ]);
33
+ return code;
34
+ }
@@ -1,9 +1,11 @@
1
1
  import React from 'react';
2
2
  import { PageConstructorProps, PageConstructorProviderProps } from '../containers/PageConstructor';
3
+ import { Theme } from '../models/common';
3
4
  import { EditorProps } from './types';
4
5
  export interface EditorContextType {
5
6
  constructorProps?: PageConstructorProps;
6
7
  providerProps?: PageConstructorProviderProps;
7
8
  deviceEmulationSettings?: EditorProps['deviceEmulationSettings'];
9
+ theme?: Theme;
8
10
  }
9
11
  export declare const EditorContext: React.Context<Partial<EditorContextType>>;
@@ -1,5 +1,6 @@
1
1
  import { PageConstructorProps, PageConstructorProviderProps } from '../../containers/PageConstructor';
2
2
  import { BlockDecorationProps, PageContent } from '../../models';
3
+ import { Theme } from '../../models/common';
3
4
  import { SchemaCustomConfig } from '../../schema';
4
5
  import { EditBlockActions } from '../components/EditBlock/EditBlock';
5
6
  export type EditorBlockId = number | string;
@@ -17,6 +18,7 @@ export interface EditorProps extends Required<Pick<PageConstructorProps, 'conten
17
18
  transformContent?: ContentTransformer;
18
19
  customSchema?: SchemaCustomConfig;
19
20
  deviceEmulationSettings?: DeviceEmulationSettings;
21
+ theme?: Theme;
20
22
  }
21
23
  export interface EditBlockEditorProps {
22
24
  isActive?: boolean;
@@ -2,12 +2,13 @@ import { __rest } from "tslib";
2
2
  import React, { useMemo } from 'react';
3
3
  import omit from 'lodash/omit';
4
4
  import { BlockIdContext } from '../../../context/blockIdContext';
5
- import { NavigationItemType } from '../../../models';
5
+ import { NavigationItemType, NavigationItemTypes } from '../../../models';
6
6
  import { block } from '../../../utils';
7
7
  import { useNavigationItemMap } from './hooks/useNavigationItemMap';
8
8
  import './NavigationItem.css';
9
9
  const b = block('navigation-item');
10
10
  const ANALYTICS_ID = 'navigation';
11
+ const nonComplexNavigationItemTypes = NavigationItemTypes.filter((type) => type !== NavigationItemType.Dropdown);
11
12
  const NavigationItem = (_a) => {
12
13
  var { data, className, menuLayout } = _a, props = __rest(_a, ["data", "className", "menuLayout"]);
13
14
  const { type = NavigationItemType.Link } = data;
@@ -15,11 +16,13 @@ const NavigationItem = (_a) => {
15
16
  const Component = navItemMap[type];
16
17
  const componentProps = useMemo(() => {
17
18
  const componentProperties = Object.assign(Object.assign({}, data), props);
18
- if (type !== NavigationItemType.Dropdown) {
19
+ if (nonComplexNavigationItemTypes.includes(type)) {
19
20
  return omit(componentProperties, 'hidePopup', 'isActive');
20
21
  }
21
- return componentProperties;
22
- }, [data, props, type]);
22
+ return NavigationItemTypes.includes(type)
23
+ ? componentProperties
24
+ : Object.assign(Object.assign({}, componentProperties), { menuLayout });
25
+ }, [data, props, type, menuLayout]);
23
26
  return (React.createElement(BlockIdContext.Provider, { value: ANALYTICS_ID },
24
27
  React.createElement("li", { className: b({ 'menu-layout': menuLayout }, className) },
25
28
  React.createElement(Component, Object.assign({}, componentProps, { className: b('content', { type }) })))));
@@ -11,7 +11,7 @@ export declare const playIconThemes: string[];
11
11
  export declare const videoControlsTypes: MediaVideoControlsType[];
12
12
  export declare const fileLinkTypes: string[];
13
13
  export declare const dividerEnum: {
14
- enum: (string | number)[];
14
+ enum: string[];
15
15
  };
16
16
  export declare const sizeNumber: {
17
17
  type: string;
@@ -835,6 +835,18 @@ export declare const BlockBaseProps: {
835
835
  context: {
836
836
  type: string;
837
837
  };
838
+ indent: {
839
+ type: string;
840
+ additionalProperties: boolean;
841
+ properties: {
842
+ top: {
843
+ enum: string[];
844
+ };
845
+ bottom: {
846
+ enum: string[];
847
+ };
848
+ };
849
+ };
838
850
  type: {};
839
851
  when: {
840
852
  type: string;
@@ -13,7 +13,7 @@ export const playIconTypes = ['default', 'text'];
13
13
  export const playIconThemes = ['blue', 'grey'];
14
14
  export const videoControlsTypes = [MediaVideoControlsType.Default, MediaVideoControlsType.Custom];
15
15
  export const fileLinkTypes = ['vertical', 'horizontal'];
16
- export const dividerEnum = { enum: [0, 'xxs', 'xs', 's', 'm', 'l', 'xl', 'xxl', 'xxxl'] };
16
+ export const dividerEnum = { enum: ['0', 'xxs', 'xs', 's', 'm', 'l', 'xl', 'xxl', 'xxxl'] };
17
17
  export const sizeNumber = { type: 'number', maximum: 12, minimum: 1 };
18
18
  export const contentThemes = ['default', 'dark', 'light'];
19
19
  export const quoteTypes = Object.values(QuoteType);
@@ -453,6 +453,13 @@ export const BlockBaseProps = Object.assign(Object.assign({}, BaseProps), { anch
453
453
  type: 'boolean',
454
454
  }, context: {
455
455
  type: 'string',
456
+ }, indent: {
457
+ type: 'object',
458
+ additionalProperties: false,
459
+ properties: {
460
+ top: dividerEnum,
461
+ bottom: dividerEnum,
462
+ },
456
463
  } });
457
464
  export const TitleProps = {
458
465
  type: 'object',
@@ -73,6 +73,9 @@ unpredictable css rules order in build */
73
73
  .pc-content_size_s .pc-content__button {
74
74
  margin-top: 8px;
75
75
  }
76
+ .pc-content_size_s .pc-content__list {
77
+ margin-top: 16px;
78
+ }
76
79
  .pc-content_size_l .pc-content__text,
77
80
  .pc-content_size_l .pc-content__notice {
78
81
  margin-top: 12px;
@@ -91,6 +94,9 @@ unpredictable css rules order in build */
91
94
  .pc-content_size_l .pc-content__button {
92
95
  margin-top: 12px;
93
96
  }
97
+ .pc-content_size_l .pc-content__list {
98
+ margin-top: 24px;
99
+ }
94
100
  .pc-content_theme_dark {
95
101
  --g-color-line-focus: var(--pc-color-line-focus-dark);
96
102
  }
@@ -46,7 +46,8 @@ const Content = (props) => {
46
46
  title && (React.createElement(Title, { className: b('title'), title: titleProps, colSizes: { all: 12 }, id: titleId })),
47
47
  text && (React.createElement("div", { className: b('text', { ['without-title']: !hasTitle }) },
48
48
  React.createElement(YFMWrapper, { content: text, modifiers: { constructor: true, [`constructor-size-${size}`]: true }, id: textId }))),
49
- (list === null || list === void 0 ? void 0 : list.length) ? React.createElement(ContentList, { list: list, size: size, qa: qaAttributes.list }) : null,
49
+ (list === null || list === void 0 ? void 0 : list.length) ? (React.createElement("div", { className: b('list') },
50
+ React.createElement(ContentList, { list: list, size: size, qa: qaAttributes.list }))) : null,
50
51
  additionalInfo && (React.createElement("div", { className: b('notice') },
51
52
  React.createElement(YFMWrapper, { content: additionalInfo, modifiers: {
52
53
  constructor: true,
@@ -6,7 +6,7 @@ export declare const Divider: {
6
6
  type: string;
7
7
  };
8
8
  size: {
9
- enum: (string | number)[];
9
+ enum: string[];
10
10
  };
11
11
  type: {};
12
12
  when: {
@@ -3,6 +3,10 @@ unpredictable css rules order in build */
3
3
  .pc-price-card {
4
4
  position: relative;
5
5
  }
6
+ .pc-price-card.pc-price-card {
7
+ min-height: auto;
8
+ }
9
+
6
10
  .pc-price-card__background {
7
11
  position: absolute;
8
12
  top: 0;
@@ -59,7 +63,8 @@ unpredictable css rules order in build */
59
63
  margin-left: 4px;
60
64
  }
61
65
  .pc-price-card__price-details {
62
- margin-bottom: 12px;
66
+ font-size: var(--g-text-body-2-font-size);
67
+ line-height: var(--g-text-body-2-line-height);
63
68
  }
64
69
  .pc-price-card__main {
65
70
  flex: 1;
@@ -69,12 +74,28 @@ unpredictable css rules order in build */
69
74
  position: relative;
70
75
  }
71
76
  .pc-price-card__info {
72
- margin-bottom: 24px;
73
77
  flex: 1;
74
78
  min-height: 0;
75
79
  display: flex;
76
80
  flex-direction: column;
77
81
  }
82
+ .pc-price-card__description:not(:last-child) {
83
+ margin-bottom: 12px;
84
+ }
85
+ .pc-price-card__links, .pc-price-card__buttons {
86
+ margin-top: 24px;
87
+ }
78
88
  .pc-price-card__links > *:not(:last-child), .pc-price-card__buttons > *:not(:last-child) {
79
89
  margin-right: 16px;
90
+ }
91
+ .pc-price-card__link {
92
+ margin-top: 0;
93
+ }
94
+ @media (max-width: 769px) {
95
+ .pc-price-card__title, .pc-price-card__price {
96
+ margin-bottom: 16px;
97
+ }
98
+ .pc-price-card__links, .pc-price-card__buttons {
99
+ margin-top: 16px;
100
+ }
80
101
  }
@@ -19,13 +19,13 @@ const PriceCard = (props) => {
19
19
  "/ ",
20
20
  pricePeriod))),
21
21
  priceDetails && (React.createElement("div", { className: b('price-details') }, priceDetails))),
22
- React.createElement("div", null, description),
22
+ description && React.createElement("div", { className: b('description') }, description),
23
23
  (list === null || list === void 0 ? void 0 : list.length) ? (React.createElement("div", { className: b('list') },
24
24
  React.createElement(ContentList, { list: list.map((item) => ({
25
25
  icon: Check,
26
26
  text: item,
27
- })), size: "s" }))) : null),
27
+ })), size: "l" }))) : null),
28
28
  buttons && (React.createElement("div", { className: b('buttons') }, buttons.map((button) => (React.createElement(Button, Object.assign({ key: button.url }, button)))))),
29
- links && (React.createElement("div", { className: b('links') }, links.map((link) => (React.createElement(LinkBlock, Object.assign({ key: link.url, textSize: "m" }, link))))))))));
29
+ links && (React.createElement("div", { className: b('links') }, links.map((link) => (React.createElement(LinkBlock, Object.assign({ className: b('link'), key: link.url, textSize: "m" }, link))))))))));
30
30
  };
31
31
  export default PriceCard;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/page-constructor",
3
- "version": "4.41.1-alpha.0",
3
+ "version": "4.42.1",
4
4
  "description": "Gravity UI Page Constructor",
5
5
  "license": "MIT",
6
6
  "repository": {