@gravity-ui/page-constructor 4.11.1 → 4.13.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 (54) hide show
  1. package/build/cjs/blocks/Icons/Icons.js +6 -1
  2. package/build/cjs/blocks/Icons/schema.d.ts +162 -0
  3. package/build/cjs/blocks/Icons/schema.js +11 -0
  4. package/build/cjs/components/BackgroundImage/BackgroundImage.d.ts +1 -0
  5. package/build/cjs/components/BackgroundImage/BackgroundImage.js +5 -2
  6. package/build/cjs/components/BackgroundMedia/BackgroundMedia.d.ts +1 -1
  7. package/build/cjs/components/BackgroundMedia/BackgroundMedia.js +4 -3
  8. package/build/cjs/components/Image/Image.js +7 -5
  9. package/build/cjs/components/Media/Image/Image.d.ts +3 -2
  10. package/build/cjs/components/Media/Image/Image.js +8 -5
  11. package/build/cjs/components/Media/Media.d.ts +2 -2
  12. package/build/cjs/components/Media/Media.js +9 -6
  13. package/build/cjs/components/Media/Video/Video.d.ts +2 -2
  14. package/build/cjs/components/Media/Video/Video.js +13 -4
  15. package/build/cjs/models/constructor-items/blocks.d.ts +7 -5
  16. package/build/cjs/models/constructor-items/common.d.ts +1 -1
  17. package/build/cjs/text-transform/common.d.ts +7 -2
  18. package/build/cjs/text-transform/common.js +8 -2
  19. package/build/cjs/text-transform/transformers.d.ts +2 -0
  20. package/build/cjs/text-transform/transformers.js +11 -8
  21. package/build/cjs/utils/blocks.d.ts +1 -1
  22. package/build/cjs/utils/blocks.js +4 -3
  23. package/build/esm/blocks/Icons/Icons.js +7 -2
  24. package/build/esm/blocks/Icons/schema.d.ts +162 -0
  25. package/build/esm/blocks/Icons/schema.js +11 -0
  26. package/build/esm/components/BackgroundImage/BackgroundImage.d.ts +1 -0
  27. package/build/esm/components/BackgroundImage/BackgroundImage.js +5 -3
  28. package/build/esm/components/BackgroundMedia/BackgroundMedia.d.ts +1 -1
  29. package/build/esm/components/BackgroundMedia/BackgroundMedia.js +5 -4
  30. package/build/esm/components/Image/Image.js +7 -5
  31. package/build/esm/components/Media/Image/Image.d.ts +3 -2
  32. package/build/esm/components/Media/Image/Image.js +8 -6
  33. package/build/esm/components/Media/Media.d.ts +2 -2
  34. package/build/esm/components/Media/Media.js +10 -7
  35. package/build/esm/components/Media/Video/Video.d.ts +2 -2
  36. package/build/esm/components/Media/Video/Video.js +14 -5
  37. package/build/esm/models/constructor-items/blocks.d.ts +7 -5
  38. package/build/esm/models/constructor-items/common.d.ts +1 -1
  39. package/build/esm/text-transform/common.d.ts +7 -2
  40. package/build/esm/text-transform/common.js +7 -2
  41. package/build/esm/text-transform/transformers.d.ts +2 -0
  42. package/build/esm/text-transform/transformers.js +11 -8
  43. package/build/esm/utils/blocks.d.ts +1 -1
  44. package/build/esm/utils/blocks.js +5 -4
  45. package/package.json +1 -1
  46. package/server/models/constructor-items/blocks.d.ts +7 -5
  47. package/server/models/constructor-items/common.d.ts +1 -1
  48. package/server/text-transform/common.d.ts +7 -2
  49. package/server/text-transform/common.js +10 -2
  50. package/server/text-transform/transformers.d.ts +2 -0
  51. package/server/text-transform/transformers.js +11 -8
  52. package/server/utils/blocks.d.ts +1 -1
  53. package/server/utils/blocks.js +4 -3
  54. package/widget/index.js +1 -1
@@ -40,7 +40,7 @@ const BLOCK_ELEMENTS = [
40
40
  'td',
41
41
  ];
42
42
  const BLOCK_ELEMENTS_REGEX = `<(${BLOCK_ELEMENTS.join('|')})[^>]*>`;
43
- const QA_ATTRIBUTES_KEYS = ['container', 'content', 'wrapper', 'image', 'button'];
43
+ const QA_ATTRIBUTES_KEYS = ['container', 'content', 'wrapper', 'image', 'button', 'animate'];
44
44
  function getHeaderTag(size) {
45
45
  switch (size) {
46
46
  case 'l':
@@ -122,13 +122,14 @@ const getShareLink = (url, type, title, text) => {
122
122
  }
123
123
  };
124
124
  exports.getShareLink = getShareLink;
125
- const getQaAttrubutes = (qa, customKeys = []) => {
125
+ const getQaAttrubutes = (qa, ...customKeys) => {
126
126
  const attributes = {};
127
127
  if (qa) {
128
- const keys = QA_ATTRIBUTES_KEYS.concat(customKeys);
128
+ const keys = QA_ATTRIBUTES_KEYS.concat((0, lodash_1.flatten)(customKeys));
129
129
  keys.forEach((key) => {
130
130
  attributes[(0, lodash_1.camelCase)(key)] = `${qa}-${key}`;
131
131
  });
132
+ attributes.default = qa;
132
133
  }
133
134
  return attributes;
134
135
  };
@@ -1,6 +1,7 @@
1
- import React, { Fragment, useContext } from 'react';
1
+ import React, { Fragment, useCallback, useContext } from 'react';
2
2
  import { Image, Title } from '../../components';
3
3
  import { LocationContext } from '../../context/locationContext';
4
+ import { useAnalytics } from '../../hooks';
4
5
  import { block, getLinkProps } from '../../utils';
5
6
  import './Icons.css';
6
7
  const b = block('icons-block');
@@ -9,12 +10,16 @@ const getItemContent = (item) => (React.createElement(Fragment, null,
9
10
  React.createElement("p", { className: b('text') }, item.text)));
10
11
  const Icons = ({ title, size = 's', items }) => {
11
12
  const { hostname } = useContext(LocationContext);
13
+ const handleAnalytics = useAnalytics();
14
+ const onClick = useCallback(({ analyticsEvents, url }) => {
15
+ handleAnalytics(analyticsEvents, { url });
16
+ }, [handleAnalytics]);
12
17
  return (React.createElement("div", { className: b({ size }) },
13
18
  title && React.createElement(Title, { className: b('header'), title: title, colSizes: { all: 12 } }),
14
19
  items.map((item) => {
15
20
  const itemContent = getItemContent(item);
16
21
  const { url, text } = item;
17
- return url ? (React.createElement("a", Object.assign({ className: b('item'), key: url, href: url, "aria-label": text, title: text }, getLinkProps(url, hostname)), itemContent)) : (React.createElement("div", { className: b('item'), key: url }, itemContent));
22
+ return url ? (React.createElement("a", Object.assign({ className: b('item'), key: url, href: url, "aria-label": text, title: text }, getLinkProps(url, hostname), { onClick: () => onClick(item) }), itemContent)) : (React.createElement("div", { className: b('item'), key: url }, itemContent));
18
23
  })));
19
24
  };
20
25
  export default Icons;
@@ -29,6 +29,87 @@ export declare const IconsProps: {
29
29
  type: string;
30
30
  };
31
31
  };
32
+ analyticsEvents: {
33
+ oneOf: ({
34
+ optionName: string;
35
+ type: string;
36
+ additionalProperties: {
37
+ type: string;
38
+ };
39
+ required: string[];
40
+ properties: {
41
+ name: {
42
+ type: string;
43
+ };
44
+ type: {
45
+ type: string;
46
+ };
47
+ counters: {
48
+ type: string;
49
+ additionalProperties: boolean;
50
+ required: never[];
51
+ properties: {
52
+ include: {
53
+ type: string;
54
+ items: {
55
+ type: string;
56
+ };
57
+ };
58
+ exclude: {
59
+ type: string;
60
+ items: {
61
+ type: string;
62
+ };
63
+ };
64
+ };
65
+ };
66
+ context: {
67
+ type: string;
68
+ };
69
+ };
70
+ items?: undefined;
71
+ } | {
72
+ type: string;
73
+ items: {
74
+ type: string;
75
+ additionalProperties: {
76
+ type: string;
77
+ };
78
+ required: string[];
79
+ properties: {
80
+ name: {
81
+ type: string;
82
+ };
83
+ type: {
84
+ type: string;
85
+ };
86
+ counters: {
87
+ type: string;
88
+ additionalProperties: boolean;
89
+ required: never[];
90
+ properties: {
91
+ include: {
92
+ type: string;
93
+ items: {
94
+ type: string;
95
+ };
96
+ };
97
+ exclude: {
98
+ type: string;
99
+ items: {
100
+ type: string;
101
+ };
102
+ };
103
+ };
104
+ };
105
+ context: {
106
+ type: string;
107
+ };
108
+ };
109
+ };
110
+ optionName: string;
111
+ })[];
112
+ };
32
113
  };
33
114
  };
34
115
  animated: {
@@ -96,6 +177,87 @@ export declare const IconsBlock: {
96
177
  type: string;
97
178
  };
98
179
  };
180
+ analyticsEvents: {
181
+ oneOf: ({
182
+ optionName: string;
183
+ type: string;
184
+ additionalProperties: {
185
+ type: string;
186
+ };
187
+ required: string[];
188
+ properties: {
189
+ name: {
190
+ type: string;
191
+ };
192
+ type: {
193
+ type: string;
194
+ };
195
+ counters: {
196
+ type: string;
197
+ additionalProperties: boolean;
198
+ required: never[];
199
+ properties: {
200
+ include: {
201
+ type: string;
202
+ items: {
203
+ type: string;
204
+ };
205
+ };
206
+ exclude: {
207
+ type: string;
208
+ items: {
209
+ type: string;
210
+ };
211
+ };
212
+ };
213
+ };
214
+ context: {
215
+ type: string;
216
+ };
217
+ };
218
+ items?: undefined;
219
+ } | {
220
+ type: string;
221
+ items: {
222
+ type: string;
223
+ additionalProperties: {
224
+ type: string;
225
+ };
226
+ required: string[];
227
+ properties: {
228
+ name: {
229
+ type: string;
230
+ };
231
+ type: {
232
+ type: string;
233
+ };
234
+ counters: {
235
+ type: string;
236
+ additionalProperties: boolean;
237
+ required: never[];
238
+ properties: {
239
+ include: {
240
+ type: string;
241
+ items: {
242
+ type: string;
243
+ };
244
+ };
245
+ exclude: {
246
+ type: string;
247
+ items: {
248
+ type: string;
249
+ };
250
+ };
251
+ };
252
+ };
253
+ context: {
254
+ type: string;
255
+ };
256
+ };
257
+ };
258
+ optionName: string;
259
+ })[];
260
+ };
99
261
  };
100
262
  };
101
263
  animated: {
@@ -1,4 +1,5 @@
1
1
  import { AnimatableProps, BlockBaseProps } from '../../schema/validators/common';
2
+ import { AnalyticsEventSchema } from '../../schema/validators/event';
2
3
  export const IconsProps = {
3
4
  additionalProperties: false,
4
5
  required: ['size', 'items'],
@@ -27,6 +28,16 @@ export const IconsProps = {
27
28
  type: 'string',
28
29
  },
29
30
  },
31
+ analyticsEvents: {
32
+ oneOf: [
33
+ Object.assign(Object.assign({}, AnalyticsEventSchema), { optionName: 'single' }),
34
+ {
35
+ type: 'array',
36
+ items: AnalyticsEventSchema,
37
+ optionName: 'list',
38
+ },
39
+ ],
40
+ },
30
41
  },
31
42
  } }),
32
43
  };
@@ -1,4 +1,5 @@
1
1
  import { BackgroundImageProps, WithChildren } from '../../models';
2
2
  import './BackgroundImage.css';
3
+ export declare const qaIdByDefault = "background-image";
3
4
  declare const BackgroundImage: (props: WithChildren<BackgroundImageProps>) => JSX.Element;
4
5
  export default BackgroundImage;
@@ -1,12 +1,14 @@
1
1
  import React from 'react';
2
- import { block } from '../../utils';
2
+ import { block, getQaAttrubutes } from '../../utils';
3
3
  import Image from '../Image/Image';
4
4
  import './BackgroundImage.css';
5
+ export const qaIdByDefault = 'background-image';
5
6
  const b = block('storage-background-image');
6
7
  const BackgroundImage = (props) => {
7
8
  const { children, src, desktop, className, imageClassName, style, hide, qa } = props;
8
- return (React.createElement("div", { className: b(null, className), style: style, "data-qa": qa },
9
- (src || desktop) && !hide && React.createElement(Image, Object.assign({}, props, { className: b('img', imageClassName) })),
9
+ const qaAttributes = getQaAttrubutes(qa || qaIdByDefault);
10
+ return (React.createElement("div", { className: b(null, className), style: style, "data-qa": qa || qaIdByDefault },
11
+ (src || desktop) && !hide && (React.createElement(Image, Object.assign({}, props, { className: b('img', imageClassName), qa: qaAttributes.image }))),
10
12
  children && React.createElement("div", { className: b('container') }, children)));
11
13
  };
12
14
  export default BackgroundImage;
@@ -1,4 +1,4 @@
1
1
  import { BackgroundMediaProps } from '../../models';
2
2
  import './BackgroundMedia.css';
3
- declare const BackgroundMedia: ({ className, color, animated, parallax, video, mediaClassName, fullWidthMedia, ...props }: BackgroundMediaProps) => JSX.Element;
3
+ declare const BackgroundMedia: ({ className, color, animated, parallax, video, mediaClassName, fullWidthMedia, qa, ...props }: BackgroundMediaProps) => JSX.Element;
4
4
  export default BackgroundMedia;
@@ -1,16 +1,17 @@
1
1
  import { __rest } from "tslib";
2
2
  import React, { useContext } from 'react';
3
3
  import { MobileContext } from '../../context/mobileContext';
4
- import { block } from '../../utils';
4
+ import { block, getQaAttrubutes } from '../../utils';
5
5
  import AnimateBlock from '../AnimateBlock/AnimateBlock';
6
6
  import Media from '../Media/Media';
7
7
  import './BackgroundMedia.css';
8
8
  const b = block('BackgroundMedia');
9
9
  const BackgroundMedia = (_a) => {
10
- var { className, color, animated, parallax = true, video, mediaClassName, fullWidthMedia } = _a, props = __rest(_a, ["className", "color", "animated", "parallax", "video", "mediaClassName", "fullWidthMedia"]);
10
+ var { className, color, animated, parallax = true, video, mediaClassName, fullWidthMedia, qa } = _a, props = __rest(_a, ["className", "color", "animated", "parallax", "video", "mediaClassName", "fullWidthMedia", "qa"]);
11
11
  const isMobile = useContext(MobileContext);
12
- return (React.createElement(AnimateBlock, { className: b(null, className), style: { backgroundColor: color }, animate: animated },
13
- React.createElement(Media, Object.assign({ className: b('media', { 'full-width-media': fullWidthMedia }, mediaClassName), imageClassName: b('image'), videoClassName: b('video'), isBackground: true }, Object.assign({ height: 720, color,
12
+ const qaAttributes = getQaAttrubutes(qa, 'media');
13
+ return (React.createElement(AnimateBlock, { className: b(null, className), style: { backgroundColor: color }, animate: animated, qa: qaAttributes.animate },
14
+ React.createElement(Media, Object.assign({ className: b('media', { 'full-width-media': fullWidthMedia }, mediaClassName), imageClassName: b('image'), videoClassName: b('video'), isBackground: true, qa: qaAttributes.media }, Object.assign({ height: 720, color,
14
15
  parallax, video: isMobile ? undefined : video }, props)))));
15
16
  };
16
17
  export default BackgroundMedia;
@@ -1,6 +1,7 @@
1
1
  import React, { Fragment, useContext, useState } from 'react';
2
2
  import { BREAKPOINTS } from '../../constants';
3
3
  import { ProjectSettingsContext } from '../../context/projectSettingsContext';
4
+ import { getQaAttrubutes } from '../../utils';
4
5
  import { isCompressible } from '../../utils/imageCompress';
5
6
  import ImageBase from '../ImageBase/ImageBase';
6
7
  import i18n from './i18n';
@@ -15,18 +16,19 @@ const Image = (props) => {
15
16
  if (!src) {
16
17
  return null;
17
18
  }
19
+ const qaAttributes = getQaAttrubutes(qa, 'mobile-webp-source', 'mobile-source', 'tablet-webp-source', 'tablet-source', 'display-source');
18
20
  const disableWebp = projectSettings.disableCompress ||
19
21
  disableCompress ||
20
22
  !isCompressible(src) ||
21
23
  imgLoadingError;
22
24
  return (React.createElement("picture", { className: containerClassName, "data-qa": qa },
23
25
  mobile && (React.createElement(Fragment, null,
24
- !disableWebp && (React.createElement("source", { srcSet: checkWebP(mobile), type: "image/webp", media: `(max-width: ${BREAKPOINTS.sm}px)` })),
25
- React.createElement("source", { srcSet: mobile, media: `(max-width: ${BREAKPOINTS.sm}px)` }))),
26
+ !disableWebp && (React.createElement("source", { srcSet: checkWebP(mobile), type: "image/webp", media: `(max-width: ${BREAKPOINTS.sm}px)`, "data-qa": qaAttributes.mobileWebpSource })),
27
+ React.createElement("source", { srcSet: mobile, media: `(max-width: ${BREAKPOINTS.sm}px)`, "data-qa": qaAttributes.mobileSource }))),
26
28
  tablet && (React.createElement(Fragment, null,
27
- !disableWebp && (React.createElement("source", { srcSet: checkWebP(tablet), type: "image/webp", media: `(max-width: ${BREAKPOINTS.md}px)` })),
28
- React.createElement("source", { srcSet: tablet, media: `(max-width: ${BREAKPOINTS.md}px)` }))),
29
- src && !disableWebp && React.createElement("source", { srcSet: checkWebP(src), type: "image/webp" }),
29
+ !disableWebp && (React.createElement("source", { srcSet: checkWebP(tablet), type: "image/webp", media: `(max-width: ${BREAKPOINTS.md}px)`, "data-qa": qaAttributes.tabletWebpSource })),
30
+ React.createElement("source", { srcSet: tablet, media: `(max-width: ${BREAKPOINTS.md}px)`, "data-qa": qaAttributes.tabletSource }))),
31
+ src && !disableWebp && (React.createElement("source", { srcSet: checkWebP(src), type: "image/webp", "data-qa": qaAttributes.displaySource })),
30
32
  React.createElement(ImageBase, { className: className, alt: alt, src: src, style: style, onClick: onClick, onError: () => setImgLoadingError(true) })));
31
33
  };
32
34
  export default Image;
@@ -1,4 +1,4 @@
1
- import { MediaComponentImageProps } from '../../../models';
1
+ import { MediaComponentImageProps, QAProps } from '../../../models';
2
2
  import './Image.css';
3
3
  export interface ImageAdditionProps {
4
4
  imageClassName?: string;
@@ -8,6 +8,7 @@ export interface ImageAdditionProps {
8
8
  interface InnerImageProps {
9
9
  hasVideoFallback: boolean;
10
10
  }
11
- type ImageAllProps = ImageAdditionProps & MediaComponentImageProps & InnerImageProps;
11
+ type ImageAllProps = ImageAdditionProps & MediaComponentImageProps & InnerImageProps & QAProps;
12
+ export declare const defaultAnimatedDivQa = "animated-div";
12
13
  declare const Image: (props: ImageAllProps) => JSX.Element;
13
14
  export default Image;
@@ -3,15 +3,17 @@ import _ from 'lodash';
3
3
  import { animated, config, useSpring } from 'react-spring';
4
4
  import SliderBlock from '../../../blocks/Slider/Slider';
5
5
  import { SliderType } from '../../../models';
6
- import { block } from '../../../utils';
6
+ import { block, getQaAttrubutes } from '../../../utils';
7
7
  import BackgroundImage from '../../BackgroundImage/BackgroundImage';
8
8
  import FullscreenImage from '../../FullscreenImage/FullscreenImage';
9
9
  import ImageView from '../../Image/Image';
10
10
  import { getMediaImage } from './utils';
11
11
  import './Image.css';
12
12
  const b = block('media-component-image');
13
+ export const defaultAnimatedDivQa = 'animated-div';
13
14
  const Image = (props) => {
14
- const { parallax, image, height, imageClassName, isBackground, hasVideoFallback, video, fullscreen, } = props;
15
+ const { parallax, image, height, imageClassName, isBackground, hasVideoFallback, video, fullscreen, qa, } = props;
16
+ const qaAttributes = getQaAttrubutes(qa, 'fullscreen-image', 'animate', 'background-image', 'image-view', 'slider-block');
15
17
  const [scrollY, setScrollY] = useState(0);
16
18
  const [{ springScrollY }, springSetScrollY] = useSpring(() => ({
17
19
  springScrollY: 0,
@@ -35,16 +37,16 @@ const Image = (props) => {
35
37
  const imageClass = b('item', { withVideo: Boolean(video) && !hasVideoFallback }, imageClassName);
36
38
  const renderFullscreenImage = (item) => {
37
39
  const itemData = getMediaImage(item);
38
- return (React.createElement(FullscreenImage, Object.assign({ key: itemData.alt }, itemData, { imageClassName: imageClass, imageStyle: { height } })));
40
+ return (React.createElement(FullscreenImage, Object.assign({ key: itemData.alt }, itemData, { imageClassName: imageClass, imageStyle: { height }, qa: qaAttributes.fullscreenImage })));
39
41
  };
40
42
  const imageBackground = (oneImage) => {
41
43
  const imageData = getMediaImage(oneImage);
42
- return (React.createElement(animated.div, { style: { transform: parallaxInterpolate || 'none' } },
43
- React.createElement(BackgroundImage, Object.assign({}, imageData, { className: imageClass, style: { height } }))));
44
+ return (React.createElement(animated.div, { style: { transform: parallaxInterpolate }, "data-qa": qaAttributes.animate },
45
+ React.createElement(BackgroundImage, Object.assign({}, imageData, { className: imageClass, style: { height }, qa: qaAttributes.backgroundImage }))));
44
46
  };
45
47
  const imageOnly = (oneImage) => {
46
48
  const imageData = getMediaImage(oneImage);
47
- return React.createElement(ImageView, Object.assign({}, imageData, { className: imageClass, style: { height } }));
49
+ return (React.createElement(ImageView, Object.assign({}, imageData, { className: imageClass, style: { height }, qa: qaAttributes.imageView })));
48
50
  };
49
51
  const imageSlider = (imageArray) => {
50
52
  const fullscreenItem = fullscreen === undefined || fullscreen;
@@ -1,8 +1,8 @@
1
- import { MediaProps } from '../../models';
1
+ import { MediaProps, QAProps } from '../../models';
2
2
  import { ImageAdditionProps } from './Image/Image';
3
3
  import { VideoAdditionProps } from './Video/Video';
4
4
  import './Media.css';
5
- export interface MediaAllProps extends MediaProps, VideoAdditionProps, ImageAdditionProps {
5
+ export interface MediaAllProps extends MediaProps, VideoAdditionProps, ImageAdditionProps, QAProps {
6
6
  className?: string;
7
7
  youtubeClassName?: string;
8
8
  }
@@ -1,5 +1,5 @@
1
1
  import React, { useMemo, useState } from 'react';
2
- import { block } from '../../utils';
2
+ import { block, getQaAttrubutes } from '../../utils';
3
3
  import YoutubeBlock from '../VideoBlock/VideoBlock';
4
4
  import DataLens from './DataLens/DataLens';
5
5
  import FullscreenVideo from './FullscreenVideo/FullscreenVideo';
@@ -8,12 +8,13 @@ import Video from './Video/Video';
8
8
  import './Media.css';
9
9
  const b = block('Media');
10
10
  export const Media = (props) => {
11
- const { image, video, youtube, dataLens, color, height, previewImg, parallax = false, metrika, fullscreen, analyticsEvents, className, imageClassName, videoClassName, youtubeClassName, playVideo = true, isBackground, playButton, customBarControlsClassName, } = props;
11
+ const { image, video, youtube, dataLens, color, height, previewImg, parallax = false, metrika, fullscreen, analyticsEvents, className, imageClassName, videoClassName, youtubeClassName, playVideo = true, isBackground, playButton, customBarControlsClassName, qa, } = props;
12
12
  const [hasVideoFallback, setHasVideoFallback] = useState(false);
13
+ const qaAttributes = getQaAttrubutes(qa, 'video');
13
14
  const content = useMemo(() => {
14
15
  let result = [];
15
16
  if (image) {
16
- result.push(React.createElement(Image, { key: "image", parallax: parallax, image: image, height: height, imageClassName: imageClassName, isBackground: isBackground, video: video, hasVideoFallback: hasVideoFallback, fullscreen: fullscreen }));
17
+ result.push(React.createElement(Image, { key: "image", parallax: parallax, image: image, height: height, imageClassName: imageClassName, isBackground: isBackground, video: video, hasVideoFallback: hasVideoFallback, fullscreen: fullscreen, qa: qaAttributes.image }));
17
18
  }
18
19
  if (video) {
19
20
  const videoProps = {
@@ -31,10 +32,10 @@ export const Media = (props) => {
31
32
  setHasVideoFallback,
32
33
  };
33
34
  if (fullscreen) {
34
- result.push(React.createElement(FullscreenVideo, Object.assign({}, videoProps)));
35
+ result.push(React.createElement(FullscreenVideo, Object.assign({}, videoProps, { qa: qaAttributes.video })));
35
36
  }
36
37
  else {
37
- result.push(React.createElement(Video, Object.assign({}, videoProps)));
38
+ result.push(React.createElement(Video, Object.assign({}, videoProps, { qa: qaAttributes.video })));
38
39
  }
39
40
  }
40
41
  if (youtube) {
@@ -54,6 +55,9 @@ export const Media = (props) => {
54
55
  imageClassName,
55
56
  isBackground,
56
57
  hasVideoFallback,
58
+ fullscreen,
59
+ qaAttributes.image,
60
+ qaAttributes.video,
57
61
  videoClassName,
58
62
  metrika,
59
63
  analyticsEvents,
@@ -62,8 +66,7 @@ export const Media = (props) => {
62
66
  playButton,
63
67
  customBarControlsClassName,
64
68
  youtubeClassName,
65
- fullscreen,
66
69
  ]);
67
- return (React.createElement("div", { className: b(null, className), style: { backgroundColor: color } }, content));
70
+ return (React.createElement("div", { className: b(null, className), style: { backgroundColor: color }, "data-qa": qa }, content));
68
71
  };
69
72
  export default Media;
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { MediaComponentVideoProps, PlayButtonProps } from '../../../models';
2
+ import { MediaComponentVideoProps, PlayButtonProps, QAProps } from '../../../models';
3
3
  import './Video.css';
4
4
  export interface VideoAdditionProps {
5
5
  playButton?: PlayButtonProps;
@@ -11,6 +11,6 @@ interface InnerVideoProps {
11
11
  setHasVideoFallback: React.Dispatch<boolean>;
12
12
  hasVideoFallback: boolean;
13
13
  }
14
- export type VideoAllProps = VideoAdditionProps & MediaComponentVideoProps & InnerVideoProps;
14
+ export type VideoAllProps = VideoAdditionProps & MediaComponentVideoProps & InnerVideoProps & QAProps;
15
15
  declare const Video: (props: VideoAllProps) => JSX.Element | null;
16
16
  export default Video;
@@ -1,12 +1,13 @@
1
1
  import React, { useEffect, useMemo, useRef } from 'react';
2
2
  import { MediaVideoType } from '../../../models';
3
- import { block } from '../../../utils';
3
+ import { block, getQaAttrubutes } from '../../../utils';
4
4
  import ReactPlayerBlock from '../../ReactPlayer/ReactPlayer';
5
5
  import { getVideoTypesWithPriority } from './utils';
6
6
  import './Video.css';
7
7
  const b = block('media-component-video');
8
8
  const Video = (props) => {
9
- const { video, height, metrika, analyticsEvents, previewImg, playButton: commonPlayButton, customBarControlsClassName, videoClassName, playVideo, setHasVideoFallback, hasVideoFallback, } = props;
9
+ const { video, height, metrika, analyticsEvents, previewImg, playButton: commonPlayButton, customBarControlsClassName, videoClassName, playVideo, setHasVideoFallback, hasVideoFallback, qa, } = props;
10
+ const qaAttributes = getQaAttrubutes(qa, 'source');
10
11
  const ref = useRef(null);
11
12
  useEffect(() => {
12
13
  if (ref && ref.current) {
@@ -42,12 +43,20 @@ const Video = (props) => {
42
43
  analyticsEvents,
43
44
  ]);
44
45
  const defaultVideoBlock = useMemo(() => {
45
- return video.src.length && !hasVideoFallback ? (React.createElement("div", { className: b('wrap', videoClassName), style: { height } },
46
+ return video.src.length && !hasVideoFallback ? (React.createElement("div", { className: b('wrap', videoClassName), style: { height }, "data-qa": qaAttributes.default },
46
47
  React.createElement("video", { disablePictureInPicture: true, playsInline: true,
47
48
  // @ts-ignore
48
49
  // eslint-disable-next-line react/no-unknown-property
49
- pip: "false", className: b('item'), ref: ref, preload: "metadata", muted: true, "aria-label": video.ariaLabel }, getVideoTypesWithPriority(video.src).map(({ src, type }, index) => (React.createElement("source", { key: index, src: src, type: type })))))) : null;
50
- }, [video, videoClassName, hasVideoFallback, height]);
50
+ pip: "false", className: b('item'), ref: ref, preload: "metadata", muted: true, "aria-label": video.ariaLabel }, getVideoTypesWithPriority(video.src).map(({ src, type }, index) => (React.createElement("source", { key: index, src: src, type: type, "data-qa": qaAttributes.source })))))) : null;
51
+ }, [
52
+ video.src,
53
+ video.ariaLabel,
54
+ hasVideoFallback,
55
+ videoClassName,
56
+ height,
57
+ qaAttributes.default,
58
+ qaAttributes.source,
59
+ ]);
51
60
  switch (video.type) {
52
61
  case MediaVideoType.Player:
53
62
  return reactPlayerBlock;
@@ -2,6 +2,7 @@
2
2
  import { ButtonSize } from '@gravity-ui/uikit';
3
3
  import { GridColumnSize, GridColumnSizesType } from '../../grid/types';
4
4
  import { ThemeSupporting } from '../../utils';
5
+ import { AnalyticsEventsBase } from '../common';
5
6
  import { AnchorProps, Animatable, BackgroundImageProps, ButtonProps, ContentSize, ContentTextSize, ContentTheme, FileLinkProps, HeaderBreadCrumbsProps, HeaderImageSize, HeaderOffset, HeaderWidth, ImageDeviceProps, Justify, LegendTableMarkerType, LinkProps, MapProps, MediaDirection, MediaProps, TextSize, TextTheme, ThemedImage, ThemedMediaProps, ThemedMediaVideoProps, TitleItemBaseProps, TitleItemProps } from './common';
6
7
  import { BannerCardProps, SubBlock, SubBlockModels } from './sub-blocks';
7
8
  export declare enum BlockType {
@@ -241,14 +242,15 @@ export interface FilterBlockProps extends Animatable, LoadableChildren {
241
242
  colSizes?: GridColumnSizesType;
242
243
  centered?: boolean;
243
244
  }
245
+ export interface IconsBlockItemProps extends AnalyticsEventsBase {
246
+ url: string;
247
+ text: string;
248
+ src: string;
249
+ }
244
250
  export interface IconsBlockProps {
245
251
  title?: string;
246
252
  size?: 's' | 'm' | 'l';
247
- items: {
248
- url: string;
249
- text: string;
250
- src: string;
251
- }[];
253
+ items: IconsBlockItemProps[];
252
254
  }
253
255
  interface ContentLayoutBlockParams {
254
256
  size?: ContentSize;
@@ -186,7 +186,7 @@ export interface MediaComponentDataLensProps {
186
186
  export interface MediaProps extends Animatable, Partial<MediaComponentDataLensProps>, Partial<MediaComponentYoutubeProps>, Partial<MediaComponentImageProps>, Partial<MediaComponentVideoProps> {
187
187
  color?: string;
188
188
  }
189
- export interface BackgroundMediaProps extends MediaProps, Animatable {
189
+ export interface BackgroundMediaProps extends MediaProps, Animatable, QAProps {
190
190
  fullWidthMedia?: boolean;
191
191
  className?: string;
192
192
  mediaClassName?: string;
@@ -1,13 +1,18 @@
1
+ import { MarkdownItPluginCb } from '@doc-tools/transform/lib/plugins/typings';
1
2
  import { Lang } from '../utils/configure';
2
3
  export type ComplexItem = {
3
4
  [key: string]: string;
4
5
  };
5
6
  export type Item = string | null | ComplexItem;
6
7
  export type Transformer = (text: string) => string;
7
- export type TransformerRaw = (lang: Lang, content: string) => string;
8
+ export type TransformerRaw = (lang: Lang, content: string, options: {
9
+ plugins: MarkdownItPluginCb[];
10
+ }) => string;
8
11
  export type Parser<T = any> = (transformer: Transformer, block: T) => T;
9
12
  export declare const createItemsParser: (fields: string[]) => (transformer: Transformer, items: Item[]) => (string | {
10
13
  [x: string]: string;
11
14
  } | null)[];
12
- export declare function yfmTransformer(lang: Lang, content: string): string;
15
+ export declare function yfmTransformer(lang: Lang, content: string, options?: {
16
+ plugins?: MarkdownItPluginCb[];
17
+ }): string;
13
18
  export declare function typografTransformer(lang: Lang, content: string): string;
@@ -1,3 +1,4 @@
1
+ import defaultPlugins from '@doc-tools/transform/lib/plugins';
1
2
  import { fullTransform, typografToHTML } from './utils';
2
3
  export const createItemsParser = (fields) => (transformer, items) => items.map((item) => {
3
4
  if (!item) {
@@ -16,8 +17,12 @@ export const createItemsParser = (fields) => (transformer, items) => items.map((
16
17
  }, {}));
17
18
  }
18
19
  });
19
- export function yfmTransformer(lang, content) {
20
- const { html } = fullTransform(content, { lang });
20
+ export function yfmTransformer(lang, content, options = {}) {
21
+ const { plugins = [] } = options;
22
+ const { html } = fullTransform(content, {
23
+ lang,
24
+ plugins: [...defaultPlugins, ...plugins],
25
+ });
21
26
  return html;
22
27
  }
23
28
  export function typografTransformer(lang, content) {
@@ -1,3 +1,4 @@
1
+ import { MarkdownItPluginCb } from '@doc-tools/transform/lib/plugins/typings';
1
2
  import { ConstructorBlock } from '../models/constructor';
2
3
  import { Lang } from '../utils/configure';
3
4
  export type ContentVariables = Record<string, string>;
@@ -9,6 +10,7 @@ export type ContentTransformerProps = {
9
10
  lang: Lang;
10
11
  customConfig?: {};
11
12
  vars?: ContentVariables;
13
+ plugins?: MarkdownItPluginCb[];
12
14
  };
13
15
  };
14
16
  export declare const contentTransformer: ({ content, options }: ContentTransformerProps) => {