@gravity-ui/page-constructor 3.8.2 → 3.9.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 (101) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +22 -0
  3. package/build/cjs/blocks/Banner/schema.d.ts +9 -3
  4. package/build/cjs/blocks/CardLayout/schema.d.ts +6 -2
  5. package/build/cjs/blocks/Companies/schema.d.ts +3 -1
  6. package/build/cjs/blocks/ContentLayout/schema.d.ts +3 -1
  7. package/build/cjs/blocks/ExtendedFeatures/schema.d.ts +6 -2
  8. package/build/cjs/blocks/FilterBlock/schema.d.ts +6 -2
  9. package/build/cjs/blocks/Header/schema.d.ts +3 -1
  10. package/build/cjs/blocks/HeaderSlider/schema.d.ts +3 -1
  11. package/build/cjs/blocks/Icons/schema.d.ts +6 -2
  12. package/build/cjs/blocks/Info/schema.d.ts +3 -1
  13. package/build/cjs/blocks/Map/schema.d.ts +3 -1
  14. package/build/cjs/blocks/Media/schema.d.ts +6 -2
  15. package/build/cjs/blocks/PromoFeaturesBlock/schema.d.ts +3 -1
  16. package/build/cjs/blocks/Questions/schema.d.ts +3 -1
  17. package/build/cjs/blocks/Share/schema.d.ts +3 -1
  18. package/build/cjs/blocks/Slider/schema.d.ts +3 -1
  19. package/build/cjs/blocks/Table/schema.d.ts +6 -2
  20. package/build/cjs/blocks/Tabs/schema.d.ts +6 -2
  21. package/build/cjs/components/Author/schema.d.ts +3 -1
  22. package/build/cjs/editor/components/AddBlock/AddBlock.css +1 -1
  23. package/build/cjs/editor/components/BlockForm/BlockForm.js +2 -2
  24. package/build/cjs/editor/components/ControlPanel/ControlPanel.css +2 -1
  25. package/build/cjs/editor/components/EditBlock/EditBlock.css +6 -6
  26. package/build/cjs/editor/components/Layout/Layout.css +4 -1
  27. package/build/cjs/editor/components/Layout/Layout.js +3 -1
  28. package/build/cjs/editor/containers/Editor/Editor.js +5 -5
  29. package/build/cjs/editor/containers/Form/Form.css +36 -18
  30. package/build/cjs/editor/containers/Form/Form.js +8 -7
  31. package/build/cjs/editor/dynamic-forms-custom/components/OneOfCustom/OneOfCustom.css +1 -1
  32. package/build/cjs/editor/types/index.d.ts +4 -1
  33. package/build/cjs/schema/constants.d.ts +18 -6
  34. package/build/cjs/schema/validators/common.d.ts +9 -3
  35. package/build/cjs/schema/validators/common.js +3 -1
  36. package/build/cjs/sub-blocks/BackgroundCard/schema.d.ts +3 -1
  37. package/build/cjs/sub-blocks/BasicCard/schema.d.ts +3 -1
  38. package/build/cjs/sub-blocks/Divider/schema.d.ts +3 -1
  39. package/build/cjs/sub-blocks/LayoutItem/schema.d.ts +3 -1
  40. package/build/cjs/sub-blocks/MediaCard/schema.d.ts +3 -1
  41. package/build/cjs/sub-blocks/PriceDetailed/schema.d.ts +3 -1
  42. package/build/cjs/sub-blocks/Quote/schema.d.ts +3 -1
  43. package/build/cjs/text-transform/filter.d.ts +20 -0
  44. package/build/cjs/text-transform/filter.js +61 -0
  45. package/build/cjs/text-transform/index.d.ts +1 -0
  46. package/build/cjs/text-transform/index.js +1 -0
  47. package/build/cjs/text-transform/transformers.d.ts +2 -0
  48. package/build/cjs/text-transform/transformers.js +3 -2
  49. package/build/esm/blocks/Banner/schema.d.ts +9 -3
  50. package/build/esm/blocks/CardLayout/schema.d.ts +6 -2
  51. package/build/esm/blocks/Companies/schema.d.ts +3 -1
  52. package/build/esm/blocks/ContentLayout/schema.d.ts +3 -1
  53. package/build/esm/blocks/ExtendedFeatures/schema.d.ts +6 -2
  54. package/build/esm/blocks/FilterBlock/schema.d.ts +6 -2
  55. package/build/esm/blocks/Header/schema.d.ts +3 -1
  56. package/build/esm/blocks/HeaderSlider/schema.d.ts +3 -1
  57. package/build/esm/blocks/Icons/schema.d.ts +6 -2
  58. package/build/esm/blocks/Info/schema.d.ts +3 -1
  59. package/build/esm/blocks/Map/schema.d.ts +3 -1
  60. package/build/esm/blocks/Media/schema.d.ts +6 -2
  61. package/build/esm/blocks/PromoFeaturesBlock/schema.d.ts +3 -1
  62. package/build/esm/blocks/Questions/schema.d.ts +3 -1
  63. package/build/esm/blocks/Share/schema.d.ts +3 -1
  64. package/build/esm/blocks/Slider/schema.d.ts +3 -1
  65. package/build/esm/blocks/Table/schema.d.ts +6 -2
  66. package/build/esm/blocks/Tabs/schema.d.ts +6 -2
  67. package/build/esm/components/Author/schema.d.ts +3 -1
  68. package/build/esm/editor/components/AddBlock/AddBlock.css +1 -1
  69. package/build/esm/editor/components/BlockForm/BlockForm.js +3 -3
  70. package/build/esm/editor/components/ControlPanel/ControlPanel.css +2 -1
  71. package/build/esm/editor/components/EditBlock/EditBlock.css +6 -6
  72. package/build/esm/editor/components/Layout/Layout.css +4 -1
  73. package/build/esm/editor/components/Layout/Layout.js +3 -1
  74. package/build/esm/editor/containers/Editor/Editor.js +5 -5
  75. package/build/esm/editor/containers/Form/Form.css +36 -18
  76. package/build/esm/editor/containers/Form/Form.js +8 -7
  77. package/build/esm/editor/dynamic-forms-custom/components/OneOfCustom/OneOfCustom.css +1 -1
  78. package/build/esm/editor/types/index.d.ts +4 -1
  79. package/build/esm/schema/constants.d.ts +18 -6
  80. package/build/esm/schema/validators/common.d.ts +9 -3
  81. package/build/esm/schema/validators/common.js +3 -1
  82. package/build/esm/sub-blocks/BackgroundCard/schema.d.ts +3 -1
  83. package/build/esm/sub-blocks/BasicCard/schema.d.ts +3 -1
  84. package/build/esm/sub-blocks/Divider/schema.d.ts +3 -1
  85. package/build/esm/sub-blocks/LayoutItem/schema.d.ts +3 -1
  86. package/build/esm/sub-blocks/MediaCard/schema.d.ts +3 -1
  87. package/build/esm/sub-blocks/PriceDetailed/schema.d.ts +3 -1
  88. package/build/esm/sub-blocks/Quote/schema.d.ts +3 -1
  89. package/build/esm/text-transform/filter.d.ts +20 -0
  90. package/build/esm/text-transform/filter.js +56 -0
  91. package/build/esm/text-transform/index.d.ts +1 -0
  92. package/build/esm/text-transform/index.js +1 -0
  93. package/build/esm/text-transform/transformers.d.ts +2 -0
  94. package/build/esm/text-transform/transformers.js +3 -2
  95. package/package.json +1 -1
  96. package/server/text-transform/filter.d.ts +20 -0
  97. package/server/text-transform/filter.js +63 -0
  98. package/server/text-transform/index.d.ts +1 -0
  99. package/server/text-transform/index.js +1 -0
  100. package/server/text-transform/transformers.d.ts +2 -0
  101. package/server/text-transform/transformers.js +3 -2
@@ -1,5 +1,5 @@
1
1
  import { __rest } from "tslib";
2
- import React, { memo, useMemo } from 'react';
2
+ import React, { Fragment, memo, useMemo } from 'react';
3
3
  import { DynamicField, SimpleVerticalAccordeon } from '@gravity-ui/dynamic-forms';
4
4
  import _ from 'lodash';
5
5
  import { Form as FinalForm, FormSpy } from 'react-final-form';
@@ -11,9 +11,9 @@ export const BlockForm = memo((_a) => {
11
11
  const prevContent = usePreviousValue(content);
12
12
  const spec = useMemo(() => (Object.assign(Object.assign({}, specRaw), { viewSpec: Object.assign(Object.assign({}, specRaw.viewSpec), { layoutOpen: active }) })), [specRaw, active]);
13
13
  if (!active) {
14
- return (React.createElement(SimpleVerticalAccordeon, { open: false, name: type, title: spec.viewSpec.layoutTitle || type, onOpenChange: onSelect }, 1));
14
+ return (React.createElement(SimpleVerticalAccordeon, { open: false, name: type, title: spec.viewSpec.layoutTitle || type, onOpenChange: onSelect }, ' '));
15
15
  }
16
- return (React.createElement(FinalForm, { initialValues: initialValues, onSubmit: _.noop }, () => (React.createElement("div", null,
16
+ return (React.createElement(FinalForm, { initialValues: initialValues, onSubmit: _.noop }, () => (React.createElement(Fragment, null,
17
17
  React.createElement(FormSpy, { onChange: ({ values }) => {
18
18
  // fix for FormSpy onChange called twice without content changes
19
19
  if (!_.isEqual(values.content, prevContent)) {
@@ -7,7 +7,8 @@ unpredictable css rules order in build */
7
7
  height: var(--editor-header-height);
8
8
  padding: 8px 20px;
9
9
  background-color: var(--yc-color-base-background);
10
- border-bottom: 1px solid var(--yc-color-line-generic);
10
+ border: 1px var(--yc-color-line-generic);
11
+ border-style: solid none;
11
12
  }
12
13
  .pc-control-panel__icon {
13
14
  display: flex;
@@ -10,7 +10,7 @@ unpredictable css rules order in build */
10
10
  height: calc(100% + 40px);
11
11
  top: -20px;
12
12
  left: -20px;
13
- border-radius: 8px;
13
+ border-radius: var(--pc-border-radius);
14
14
  z-index: 100;
15
15
  }
16
16
  .pc-edit-block__controls_isHeader {
@@ -25,7 +25,7 @@ unpredictable css rules order in build */
25
25
  .pc-edit-block__controls-content {
26
26
  display: flex;
27
27
  position: absolute;
28
- bottom: -44px;
28
+ bottom: -40px;
29
29
  left: 50%;
30
30
  transform: translateX(-50%);
31
31
  }
@@ -34,14 +34,14 @@ unpredictable css rules order in build */
34
34
  justify-content: center;
35
35
  align-items: center;
36
36
  transition: transform 0.2s;
37
- width: 24px;
38
- height: 24px;
39
- border-radius: calc(8px / 2);
37
+ width: 48px;
38
+ height: 32px;
39
+ border-radius: 8px;
40
40
  background-color: var(--yc-color-promo-highlight-neon);
41
41
  }
42
42
  .pc-edit-block__control:hover {
43
43
  transform: scale(1.1);
44
44
  }
45
45
  .pc-edit-block__control:not(:first-child) {
46
- margin-left: 12px;
46
+ margin-left: 4px;
47
47
  }
@@ -29,11 +29,14 @@ unpredictable css rules order in build */
29
29
  }
30
30
  .pc-editor-layout__left {
31
31
  flex: 0 0 auto;
32
- padding: 8px 20px 20px;
32
+ padding: 24px 16px;
33
33
  width: var(--editor-left-column-width);
34
34
  border-right: var(--editor-divider-width) solid var(--yc-color-line-generic);
35
35
  overflow-x: auto;
36
36
  }
37
37
  .pc-editor-layout__right {
38
38
  width: 100%;
39
+ }
40
+ .pc-editor-layout__right_editing {
41
+ padding-bottom: 200px;
39
42
  }
@@ -1,5 +1,6 @@
1
1
  import React, { Children, Fragment } from 'react';
2
2
  import { block } from '../../../utils';
3
+ import { ViewModeItem } from '../../types';
3
4
  import ControlPanel from '../ControlPanel/ControlPanel';
4
5
  import './Layout.css';
5
6
  const b = block('editor-layout');
@@ -7,6 +8,7 @@ const Left = () => null;
7
8
  const Right = () => null;
8
9
  const Layout = ({ children, mode, onModeChange }) => {
9
10
  let left, right;
11
+ const isEditingMode = mode === ViewModeItem.Edititng;
10
12
  function handleChild(child) {
11
13
  switch (child === null || child === void 0 ? void 0 : child.type) {
12
14
  case Left:
@@ -25,7 +27,7 @@ const Layout = ({ children, mode, onModeChange }) => {
25
27
  React.createElement("div", { className: b('container') },
26
28
  React.createElement(Fragment, null,
27
29
  left && React.createElement("div", { className: b('left') }, left),
28
- right && React.createElement("div", { className: b('right') }, right)))));
30
+ right && React.createElement("div", { className: b('right', { editing: isEditingMode }) }, right)))));
29
31
  };
30
32
  Layout.Left = Left;
31
33
  Layout.Right = Right;
@@ -12,8 +12,9 @@ import { Form } from '../Form/Form';
12
12
  export const Editor = (_a) => {
13
13
  var { children, customSchema, onChange } = _a, rest = __rest(_a, ["children", "customSchema", "onChange"]);
14
14
  const { content, activeBlockIndex, errorBoundaryState, viewMode, onContentUpdate, onViewModeUpdate, onAdd, onSelect, injectEditBlockProps, } = useEditorState(rest);
15
+ const formSpecs = useFormSpec(customSchema);
15
16
  const isEditingMode = viewMode === ViewModeItem.Edititng;
16
- const constructorProps = useMemo(() => {
17
+ const outgoingProps = useMemo(() => {
17
18
  const custom = isEditingMode
18
19
  ? addCustomDecorator([
19
20
  (props) => (React.createElement(EditBlock, Object.assign({}, injectEditBlockProps(props)))),
@@ -21,16 +22,15 @@ export const Editor = (_a) => {
21
22
  (props) => (React.createElement(ErrorBoundary, Object.assign({}, props, { key: `${getBlockId(props)}-${errorBoundaryState}` }))),
22
23
  ], rest.custom)
23
24
  : rest.custom;
24
- return { content, custom };
25
- }, [injectEditBlockProps, content, errorBoundaryState, isEditingMode, rest.custom]);
25
+ return { content, custom, viewMode };
26
+ }, [injectEditBlockProps, content, errorBoundaryState, isEditingMode, viewMode, rest.custom]);
26
27
  useEffect(() => {
27
28
  onChange === null || onChange === void 0 ? void 0 : onChange(content);
28
29
  }, [content, onChange]);
29
- const formSpecs = useFormSpec(customSchema);
30
30
  return (React.createElement(Layout, { mode: viewMode, onModeChange: onViewModeUpdate },
31
31
  isEditingMode && (React.createElement(Layout.Left, null,
32
32
  React.createElement(Form, { content: content, onChange: onContentUpdate, activeBlockIndex: activeBlockIndex, onSelect: onSelect, spec: formSpecs }))),
33
33
  React.createElement(Layout.Right, null,
34
- React.createElement(ErrorBoundary, { key: errorBoundaryState }, children(constructorProps)),
34
+ React.createElement(ErrorBoundary, { key: errorBoundaryState }, children(outgoingProps)),
35
35
  isEditingMode && React.createElement(AddBlock, { onAdd: onAdd }))));
36
36
  };
@@ -3,14 +3,14 @@ unpredictable css rules order in build */
3
3
  .pc-editor-form {
4
4
  --top-level-font-size: var(--yc-text-display-2-font-size);
5
5
  --top-level-line-height: var(--yc-text-display-2-line-height);
6
- --block-propery-font-size: var(--yc-text-body-3-font-size);
7
- --block-property-line-height: var(--yc-text-body-3-line-height);
8
- --nested-property-font-size: var(--yc-text-body-1-font-size);
9
- --nested-property-line-height: var(--yc-text-body-1-line-height);
10
- --complex-nested-property-font-size: var(--yc-text-body-2-font-size);
11
- --complex-nested-property-line-height: var(--yc-text-body-2-line-height);
6
+ --block-level-complex-propery-font-size: var(--yc-text-body-3-font-size);
7
+ --block-level-complex-property-line-height: var(--yc-text-body-3-line-height);
8
+ --complex-property-font-size: var(--yc-text-body-2-font-size);
9
+ --complex-property-line-height: var(--yc-text-body-2-line-height);
10
+ --property-font-size: var(--yc-text-body-1-font-size);
11
+ --property-line-height: var(--yc-text-body-1-line-height);
12
12
  --input-min-width: 150px;
13
- --property-title-width: 140px;
13
+ --property-title-width: 96px;
14
14
  --button-height: 48px;
15
15
  --icon-size: 32px;
16
16
  --icon-margin: 42px;
@@ -24,20 +24,23 @@ unpredictable css rules order in build */
24
24
  --button-height: 32px;
25
25
  --icon-size: 20px;
26
26
  --icon-margin: 30px;
27
- --header-text-size: var(--block-propery-font-size);
28
- --header-line-height: var(--block-property-line-height);
29
- --text-size: var(--block-propery-font-size);
30
- --line-height: var(--block-property-line-height);
27
+ --header-text-size: var(--block-level-complex-propery-font-size);
28
+ --header-line-height: var(--block-level-complex-property-line-height);
29
+ --text-size: var(--property-font-size);
30
+ --line-height: var(--property-line-height);
31
+ --property-font-weight: 400;
31
32
  }
32
33
  .pc-editor-form .df-use-search .df-use-search .df-use-search {
33
34
  --button-height: 28px;
34
35
  --icon-size: 16px;
35
36
  --icon-margin: 25px;
36
37
  --property-font-weight: 400;
37
- --header-text-size: var(--complex-nested-property-font-size);
38
- --header-line-height: var(--complex-nested-property-line-height);
39
- --text-size: var(--nested-property-font-size);
40
- --line-height: var(--nested-property-line-height);
38
+ --header-text-size: var(--complex-property-font-size);
39
+ --header-line-height: var(--complex-property-line-height);
40
+ --text-size: var(--property-font-size);
41
+ --line-height: var(--property-line-height);
42
+ --oneof-text-size: var(--complex-propery-font-size);
43
+ --oneof-line-height: var(--complex-property-line-height);
41
44
  }
42
45
  .pc-editor-form .df-row {
43
46
  width: inherit;
@@ -73,17 +76,29 @@ unpredictable css rules order in build */
73
76
  .pc-editor-form .df-simple-vertical-accordeon__header .yc-button .yc-button__icon_side_right ~ .yc-button__text {
74
77
  margin-right: var(--icon-margin);
75
78
  }
79
+ .pc-editor-form .df-simple-vertical-accordeon__body {
80
+ margin-top: 0px;
81
+ padding-top: 12px;
82
+ }
83
+ .pc-editor-form .df-use-search {
84
+ margin: 4px 0;
85
+ }
76
86
  .pc-editor-form .df-simple-vertical-accordeon__body,
77
87
  .pc-editor-form .df-group-indent > .df-use-search {
78
88
  margin-top: 0;
79
89
  margin-left: 1px;
80
- padding-top: 12px;
81
- padding-left: 16px;
90
+ padding-top: 4px;
91
+ padding-bottom: 4px;
92
+ padding-left: 12px;
82
93
  border-left: 1px solid var(--yc-color-line-generic-accent);
83
94
  }
95
+ .pc-editor-form .df-simple-vertical-accordeon_branch .df-simple-vertical-accordeon__body {
96
+ padding-left: 12px;
97
+ }
84
98
  .pc-editor-form .g-select,
85
99
  .pc-editor-form .yc-text-input {
86
- width: var(--input-min-width);
100
+ min-width: var(--input-min-width);
101
+ width: 100%;
87
102
  }
88
103
  .pc-editor-form + .pc-editor-form {
89
104
  margin-top: 12px;
@@ -91,4 +106,7 @@ unpredictable css rules order in build */
91
106
  .pc-editor-form__tabs {
92
107
  --yc-color-base-special: var(--yc-color-promo-base-neon);
93
108
  margin-bottom: 20px;
109
+ }
110
+ .pc-editor-form__block-form {
111
+ margin-bottom: 16px;
94
112
  }
@@ -28,13 +28,14 @@ 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(BlockForm, { spec: blocksSpec[blockData.type], key: getBlockKey(blockData, index), data: blockData, active: activeBlockIndex === index, onChange: (data) => {
32
- onChange(Object.assign(Object.assign({}, content), { blocks: [
33
- ...blocks.slice(0, index),
34
- data,
35
- ...blocks.slice(index + 1),
36
- ] }));
37
- }, onSelect: () => onSelect(index) })) : null)));
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) => {
33
+ onChange(Object.assign(Object.assign({}, content), { blocks: [
34
+ ...blocks.slice(0, index),
35
+ data,
36
+ ...blocks.slice(index + 1),
37
+ ] }));
38
+ }, onSelect: () => onSelect(index) }))) : null)));
38
39
  break;
39
40
  }
40
41
  }
@@ -10,7 +10,7 @@
10
10
  }
11
11
  .pc-one-of-custom .df-group-indent > .df-use-search {
12
12
  padding-top: 11px;
13
- padding-left: 20px;
13
+ padding-left: 12px;
14
14
  margin-top: 4px;
15
15
  margin-bottom: 20px;
16
16
  margin-left: 5px;
@@ -4,8 +4,11 @@ import { BlockDecorationProps, PageContent } from '../../models';
4
4
  import { SchemaCustomConfig } from '../../schema';
5
5
  import { EditBlockActions } from '../components/EditBlock/EditBlock';
6
6
  export type EditorBlockId = number | string;
7
+ export interface EditorOutgoingProps extends Partial<PageConstructorProps> {
8
+ viewMode: ViewModeItem;
9
+ }
7
10
  export interface EditorProps extends Required<Pick<PageConstructorProps, 'content'>>, Partial<Omit<PageConstructorProps, 'content'>> {
8
- children: (props: Partial<PageConstructorProps>) => React.ReactNode;
11
+ children: (props: EditorOutgoingProps) => React.ReactNode;
9
12
  onChange?: (data: PageContent) => void;
10
13
  customSchema?: SchemaCustomConfig;
11
14
  }
@@ -91,7 +91,9 @@ export declare const cardSchemas: {
91
91
  enum: string[];
92
92
  };
93
93
  type: {};
94
- when: {};
94
+ when: {
95
+ type: string;
96
+ };
95
97
  };
96
98
  };
97
99
  quote: {
@@ -166,7 +168,9 @@ export declare const cardSchemas: {
166
168
  };
167
169
  };
168
170
  type: {};
169
- when: {};
171
+ when: {
172
+ type: string;
173
+ };
170
174
  };
171
175
  };
172
176
  'background-card': {
@@ -280,7 +284,9 @@ export declare const cardSchemas: {
280
284
  enum: string[];
281
285
  };
282
286
  type: {};
283
- when: {};
287
+ when: {
288
+ type: string;
289
+ };
284
290
  };
285
291
  };
286
292
  'price-detailed': {
@@ -372,7 +378,9 @@ export declare const cardSchemas: {
372
378
  type: string;
373
379
  };
374
380
  type: {};
375
- when: {};
381
+ when: {
382
+ type: string;
383
+ };
376
384
  };
377
385
  };
378
386
  'banner-card': {
@@ -665,7 +673,9 @@ export declare const cardSchemas: {
665
673
  type: string;
666
674
  };
667
675
  type: {};
668
- when: {};
676
+ when: {
677
+ type: string;
678
+ };
669
679
  };
670
680
  };
671
681
  'media-card': {
@@ -899,7 +909,9 @@ export declare const cardSchemas: {
899
909
  enum: string[];
900
910
  };
901
911
  type: {};
902
- when: {};
912
+ when: {
913
+ type: string;
914
+ };
903
915
  };
904
916
  };
905
917
  };
@@ -21,7 +21,9 @@ export declare const sizeNumber: {
21
21
  export declare const contentThemes: string[];
22
22
  export declare const BaseProps: {
23
23
  type: {};
24
- when: {};
24
+ when: {
25
+ type: string;
26
+ };
25
27
  };
26
28
  export declare const containerSizesObject: {
27
29
  type: string;
@@ -412,7 +414,9 @@ export declare const LinkProps: {
412
414
  })[];
413
415
  };
414
416
  type: {};
415
- when: {};
417
+ when: {
418
+ type: string;
419
+ };
416
420
  };
417
421
  };
418
422
  export declare const FileLinkProps: {
@@ -750,7 +754,9 @@ export declare const BlockBaseProps: {
750
754
  type: string;
751
755
  };
752
756
  type: {};
753
- when: {};
757
+ when: {
758
+ type: string;
759
+ };
754
760
  };
755
761
  export declare const TitleProps: {
756
762
  type: string;
@@ -18,7 +18,9 @@ export const sizeNumber = { type: 'number', maximum: 12, minimum: 1 };
18
18
  export const contentThemes = ['default', 'dark', 'light'];
19
19
  export const BaseProps = {
20
20
  type: {},
21
- when: {},
21
+ when: {
22
+ type: 'string',
23
+ },
22
24
  };
23
25
  export const containerSizesObject = {
24
26
  type: 'object',
@@ -110,7 +110,9 @@ export declare const BackgroundCard: {
110
110
  enum: string[];
111
111
  };
112
112
  type: {};
113
- when: {};
113
+ when: {
114
+ type: string;
115
+ };
114
116
  };
115
117
  };
116
118
  };
@@ -89,7 +89,9 @@ export declare const BasicCard: {
89
89
  enum: string[];
90
90
  };
91
91
  type: {};
92
- when: {};
92
+ when: {
93
+ type: string;
94
+ };
93
95
  };
94
96
  };
95
97
  };
@@ -9,7 +9,9 @@ export declare const Divider: {
9
9
  enum: (string | number)[];
10
10
  };
11
11
  type: {};
12
- when: {};
12
+ when: {
13
+ type: string;
14
+ };
13
15
  };
14
16
  };
15
17
  };
@@ -308,6 +308,8 @@ export declare const LayoutItem: {
308
308
  type: string;
309
309
  };
310
310
  type: {};
311
- when: {};
311
+ when: {
312
+ type: string;
313
+ };
312
314
  };
313
315
  };
@@ -230,7 +230,9 @@ export declare const MediaCardBlock: {
230
230
  enum: string[];
231
231
  };
232
232
  type: {};
233
- when: {};
233
+ when: {
234
+ type: string;
235
+ };
234
236
  };
235
237
  };
236
238
  };
@@ -88,7 +88,9 @@ export declare const PriceDetailedBlock: {
88
88
  type: string;
89
89
  };
90
90
  type: {};
91
- when: {};
91
+ when: {
92
+ type: string;
93
+ };
92
94
  };
93
95
  };
94
96
  };
@@ -71,7 +71,9 @@ export declare const Quote: {
71
71
  };
72
72
  };
73
73
  type: {};
74
- when: {};
74
+ when: {
75
+ type: string;
76
+ };
75
77
  };
76
78
  };
77
79
  };
@@ -0,0 +1,20 @@
1
+ import { ContentVariables } from './transformers';
2
+ type WhenValue = string | boolean | undefined;
3
+ type OrArray<T> = T | T[];
4
+ type OrArrayRecord<T> = Record<string, OrArray<T>>;
5
+ interface FilteredContentItem extends OrArrayRecord<FilteredContentItem> {
6
+ }
7
+ type FilteredContent = OrArray<FilteredContentItem>;
8
+ type FilterableContentItem = FilteredContentItem & {
9
+ when: WhenValue;
10
+ };
11
+ export type FilterableContent = OrArray<FilterableContentItem>;
12
+ /**
13
+ * Filters content recoursively by result of it's 'when' property evaluation applied to vars argument.
14
+ * e.g. property {..., when: 'someVar == "someValue"' } will be included in result only if vars.someVar === 'someValue'
15
+ * @param {FilterableContent} content
16
+ * @param {ContentVariables} vars
17
+ * @return {FilteredContent}
18
+ */
19
+ export declare function filterContent(content: FilterableContent | FilteredContent, vars: ContentVariables): FilteredContent;
20
+ export {};
@@ -0,0 +1,56 @@
1
+ /* eslint-disable no-param-reassign */
2
+ /* eslint-disable no-not-accumulator-reassign/no-not-accumulator-reassign */
3
+ import evalExp from '@doc-tools/transform/lib/liquid/evaluation';
4
+ function filterItems(items, vars, propertyName) {
5
+ if (!Array.isArray(items)) {
6
+ throw new Error(`Error while filtering: items has invalid key '${propertyName}' equals ${JSON.stringify(items)}`);
7
+ }
8
+ return items.reduce((result, item) => {
9
+ const passedFiltration = checkWhenCondition(item.when, vars);
10
+ if (passedFiltration) {
11
+ const property = propertyName && item[propertyName];
12
+ if (property === undefined) {
13
+ result.push(item);
14
+ }
15
+ else {
16
+ const filteredProperty = filterItems(property, vars, propertyName);
17
+ if (filteredProperty.length !== 0) {
18
+ result.push(Object.assign(Object.assign({}, item), { [propertyName]: filteredProperty }));
19
+ }
20
+ }
21
+ }
22
+ return result;
23
+ }, []);
24
+ }
25
+ function checkWhenCondition(whenValue, vars) {
26
+ return (whenValue === true ||
27
+ whenValue === undefined ||
28
+ (typeof whenValue === 'string' && (!whenValue || evalExp(whenValue, vars))));
29
+ }
30
+ function isItemArray(content) {
31
+ return Array.isArray(content);
32
+ }
33
+ function isItem(content) {
34
+ return content && typeof content === 'object' && !Array.isArray(content);
35
+ }
36
+ /**
37
+ * Filters content recoursively by result of it's 'when' property evaluation applied to vars argument.
38
+ * e.g. property {..., when: 'someVar == "someValue"' } will be included in result only if vars.someVar === 'someValue'
39
+ * @param {FilterableContent} content
40
+ * @param {ContentVariables} vars
41
+ * @return {FilteredContent}
42
+ */
43
+ export function filterContent(content, vars) {
44
+ if (isItemArray(content)) {
45
+ return filterItems(content, vars).map((item) => filterContent(item, vars));
46
+ }
47
+ else if (isItem(content)) {
48
+ return Object.entries(content).reduce((acc, [key, value]) => {
49
+ acc[key] = filterContent(value, vars);
50
+ return acc;
51
+ }, {});
52
+ }
53
+ else {
54
+ return content;
55
+ }
56
+ }
@@ -2,3 +2,4 @@ export * from './utils';
2
2
  export * from './config';
3
3
  export * from './common';
4
4
  export * from './transformers';
5
+ export * from './filter';
@@ -2,3 +2,4 @@ export * from './utils';
2
2
  export * from './config';
3
3
  export * from './common';
4
4
  export * from './transformers';
5
+ export * from './filter';
@@ -1,5 +1,6 @@
1
1
  import { ConstructorBlock } from '../models/constructor';
2
2
  import { Lang } from '../utils/configure';
3
+ export type ContentVariables = Record<string, string>;
3
4
  export type ContentTransformerProps = {
4
5
  content: {
5
6
  blocks?: ConstructorBlock[];
@@ -7,6 +8,7 @@ export type ContentTransformerProps = {
7
8
  options: {
8
9
  lang: Lang;
9
10
  customConfig?: {};
11
+ vars?: ContentVariables;
10
12
  };
11
13
  };
12
14
  export declare const contentTransformer: ({ content, options }: ContentTransformerProps) => {
@@ -2,6 +2,7 @@
2
2
  /* eslint-disable no-not-accumulator-reassign/no-not-accumulator-reassign */
3
3
  import _ from 'lodash';
4
4
  import { config } from './config';
5
+ import { filterContent } from './filter';
5
6
  function transformBlocks(blocks, lang, customConfig = {}) {
6
7
  const fullConfig = Object.assign(Object.assign({}, config), customConfig);
7
8
  const clonedBlocks = _.cloneDeep(blocks);
@@ -42,8 +43,8 @@ function transformBlock(lang, blocksConfig, block) {
42
43
  return block;
43
44
  }
44
45
  export const contentTransformer = ({ content, options }) => {
45
- const { lang, customConfig = {} } = options;
46
- const { blocks = [] } = content;
46
+ const { lang, customConfig = {}, vars } = options;
47
+ const { blocks = [] } = (vars ? filterContent(content, vars) : content);
47
48
  const transformedBlocks = transformBlocks(blocks, lang, customConfig);
48
49
  return {
49
50
  blocks: transformedBlocks,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/page-constructor",
3
- "version": "3.8.2",
3
+ "version": "3.9.0",
4
4
  "description": "Gravity UI Page Constructor",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -0,0 +1,20 @@
1
+ import { ContentVariables } from './transformers';
2
+ type WhenValue = string | boolean | undefined;
3
+ type OrArray<T> = T | T[];
4
+ type OrArrayRecord<T> = Record<string, OrArray<T>>;
5
+ interface FilteredContentItem extends OrArrayRecord<FilteredContentItem> {
6
+ }
7
+ type FilteredContent = OrArray<FilteredContentItem>;
8
+ type FilterableContentItem = FilteredContentItem & {
9
+ when: WhenValue;
10
+ };
11
+ export type FilterableContent = OrArray<FilterableContentItem>;
12
+ /**
13
+ * Filters content recoursively by result of it's 'when' property evaluation applied to vars argument.
14
+ * e.g. property {..., when: 'someVar == "someValue"' } will be included in result only if vars.someVar === 'someValue'
15
+ * @param {FilterableContent} content
16
+ * @param {ContentVariables} vars
17
+ * @return {FilteredContent}
18
+ */
19
+ export declare function filterContent(content: FilterableContent | FilteredContent, vars: ContentVariables): FilteredContent;
20
+ export {};