@gravity-ui/page-constructor 1.14.0 → 1.15.0-alpha.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 (73) hide show
  1. package/build/cjs/blocks/Banner/schema.d.ts +216 -0
  2. package/build/cjs/blocks/Media/schema.d.ts +72 -0
  3. package/build/cjs/components/Button/Button.js +5 -2
  4. package/build/cjs/components/CardBase/CardBase.d.ts +2 -0
  5. package/build/cjs/components/CardBase/CardBase.js +4 -1
  6. package/build/cjs/components/HeaderBreadcrumbs/HeaderBreadcrumbs.js +4 -1
  7. package/build/cjs/components/Link/Link.js +4 -1
  8. package/build/cjs/components/Media/Media.js +3 -2
  9. package/build/cjs/components/Media/Video/Video.js +4 -3
  10. package/build/cjs/components/ReactPlayer/ReactPlayer.js +27 -3
  11. package/build/cjs/components/YandexForm/YandexForm.d.ts +2 -0
  12. package/build/cjs/components/YandexForm/YandexForm.js +13 -2
  13. package/build/cjs/containers/PageConstructor/Provider.d.ts +2 -0
  14. package/build/cjs/containers/PageConstructor/Provider.js +3 -1
  15. package/build/cjs/context/analyticsContext/analyticsContext.d.ts +6 -0
  16. package/build/cjs/context/analyticsContext/analyticsContext.js +6 -0
  17. package/build/cjs/context/analyticsContext/index.d.ts +1 -0
  18. package/build/cjs/context/analyticsContext/index.js +4 -0
  19. package/build/cjs/context/metrikaContext/metrikaContext.d.ts +6 -0
  20. package/build/cjs/hooks/index.d.ts +1 -0
  21. package/build/cjs/hooks/index.js +1 -0
  22. package/build/cjs/hooks/useAnalytics.d.ts +2 -0
  23. package/build/cjs/hooks/useAnalytics.js +18 -0
  24. package/build/cjs/hooks/useMetrika.d.ts +6 -0
  25. package/build/cjs/hooks/useMetrika.js +8 -0
  26. package/build/cjs/models/common.d.ts +36 -0
  27. package/build/cjs/models/common.js +3 -0
  28. package/build/cjs/models/constructor-items/common.d.ts +6 -1
  29. package/build/cjs/models/constructor-items/sub-blocks.d.ts +2 -1
  30. package/build/cjs/schema/validators/common.d.ts +156 -0
  31. package/build/cjs/schema/validators/common.js +10 -0
  32. package/build/cjs/schema/validators/event.d.ts +88 -0
  33. package/build/cjs/schema/validators/event.js +89 -0
  34. package/build/cjs/sub-blocks/HubspotForm/index.js +13 -2
  35. package/build/esm/blocks/Banner/schema.d.ts +216 -0
  36. package/build/esm/blocks/Media/schema.d.ts +72 -0
  37. package/build/esm/components/Button/Button.js +5 -2
  38. package/build/esm/components/CardBase/CardBase.d.ts +2 -0
  39. package/build/esm/components/CardBase/CardBase.js +4 -1
  40. package/build/esm/components/HeaderBreadcrumbs/HeaderBreadcrumbs.js +4 -1
  41. package/build/esm/components/Link/Link.js +4 -1
  42. package/build/esm/components/Media/Media.js +3 -2
  43. package/build/esm/components/Media/Video/Video.js +4 -3
  44. package/build/esm/components/ReactPlayer/ReactPlayer.js +27 -3
  45. package/build/esm/components/YandexForm/YandexForm.d.ts +2 -0
  46. package/build/esm/components/YandexForm/YandexForm.js +13 -2
  47. package/build/esm/containers/PageConstructor/Provider.d.ts +2 -0
  48. package/build/esm/containers/PageConstructor/Provider.js +3 -1
  49. package/build/esm/context/analyticsContext/analyticsContext.d.ts +6 -0
  50. package/build/esm/context/analyticsContext/analyticsContext.js +2 -0
  51. package/build/esm/context/analyticsContext/index.d.ts +1 -0
  52. package/build/esm/context/analyticsContext/index.js +1 -0
  53. package/build/esm/context/metrikaContext/metrikaContext.d.ts +6 -0
  54. package/build/esm/hooks/index.d.ts +1 -0
  55. package/build/esm/hooks/index.js +1 -0
  56. package/build/esm/hooks/useAnalytics.d.ts +2 -0
  57. package/build/esm/hooks/useAnalytics.js +14 -0
  58. package/build/esm/hooks/useMetrika.d.ts +6 -0
  59. package/build/esm/hooks/useMetrika.js +8 -0
  60. package/build/esm/models/common.d.ts +36 -0
  61. package/build/esm/models/common.js +3 -0
  62. package/build/esm/models/constructor-items/common.d.ts +6 -1
  63. package/build/esm/models/constructor-items/sub-blocks.d.ts +2 -1
  64. package/build/esm/schema/validators/common.d.ts +156 -0
  65. package/build/esm/schema/validators/common.js +10 -0
  66. package/build/esm/schema/validators/event.d.ts +88 -0
  67. package/build/esm/schema/validators/event.js +86 -0
  68. package/build/esm/sub-blocks/HubspotForm/index.js +14 -3
  69. package/package.json +4 -1
  70. package/server/models/common.d.ts +36 -0
  71. package/server/models/common.js +3 -0
  72. package/server/models/constructor-items/common.d.ts +6 -1
  73. package/server/models/constructor-items/sub-blocks.d.ts +2 -1
@@ -12,8 +12,9 @@ const b = (0, utils_1.block)('hubspot-form');
12
12
  const HubspotForm = (props) => {
13
13
  const { className, theme: themeProp, isMobile: isMobileProp, formId, formInstanceId, portalId, region, formClassName, pixelEvents,
14
14
  // hubspotEvents, // TODO: decide how to handle them
15
- onBeforeSubmit, onSubmit, onBeforeLoad, onLoad, } = props;
15
+ analyticsEvents, onBeforeSubmit, onSubmit, onBeforeLoad, onLoad, } = props;
16
16
  const handleMetrika = (0, useMetrika_1.useMetrika)();
17
+ const handleAnalytics = (0, hooks_1.useAnalytics)();
17
18
  const { themeValue } = (0, react_1.useContext)(ThemeValueContext_1.ThemeValueContext);
18
19
  const isMobileValue = (0, react_1.useContext)(mobileContext_1.MobileContext);
19
20
  const theme = themeProp !== null && themeProp !== void 0 ? themeProp : themeValue;
@@ -24,9 +25,19 @@ const HubspotForm = (props) => {
24
25
  onLoad,
25
26
  onSubmit: (e) => {
26
27
  handleMetrika === null || handleMetrika === void 0 ? void 0 : handleMetrika({ pixelEvents });
28
+ handleAnalytics === null || handleAnalytics === void 0 ? void 0 : handleAnalytics(analyticsEvents);
27
29
  onSubmit === null || onSubmit === void 0 ? void 0 : onSubmit(e);
28
30
  },
29
- }), [onBeforeLoad, onBeforeSubmit, onLoad, handleMetrika, pixelEvents, onSubmit]);
31
+ }), [
32
+ onBeforeLoad,
33
+ onBeforeSubmit,
34
+ onLoad,
35
+ handleMetrika,
36
+ pixelEvents,
37
+ handleAnalytics,
38
+ analyticsEvents,
39
+ onSubmit,
40
+ ]);
30
41
  (0, hooks_1.useHandleHubspotEvents)(handlers, formId);
31
42
  return (react_1.default.createElement(HubspotFormContainer_1.default, { key: [formClassName, formId, formInstanceId, portalId, region].join(), className: b({ theme, mobile }, className), formClassName: formClassName, formId: formId, portalId: portalId, formInstanceId: formInstanceId, region: region }));
32
43
  };
@@ -173,6 +173,78 @@ export declare const BannerCardProps: {
173
173
  };
174
174
  };
175
175
  };
176
+ analyticsEvents: {
177
+ anyOf: ({
178
+ type: string;
179
+ additionalProperties: {
180
+ type: string;
181
+ };
182
+ required: string[];
183
+ properties: {
184
+ name: {
185
+ type: string;
186
+ };
187
+ type: {
188
+ type: string;
189
+ };
190
+ counters: {
191
+ type: string;
192
+ additionalProperties: boolean;
193
+ required: never[];
194
+ properties: {
195
+ include: {
196
+ type: string;
197
+ items: {
198
+ type: string;
199
+ };
200
+ };
201
+ exclude: {
202
+ type: string;
203
+ items: {
204
+ type: string;
205
+ };
206
+ };
207
+ };
208
+ };
209
+ };
210
+ } | {
211
+ type: string;
212
+ items: {
213
+ type: string;
214
+ additionalProperties: {
215
+ type: string;
216
+ };
217
+ required: string[];
218
+ properties: {
219
+ name: {
220
+ type: string;
221
+ };
222
+ type: {
223
+ type: string;
224
+ };
225
+ counters: {
226
+ type: string;
227
+ additionalProperties: boolean;
228
+ required: never[];
229
+ properties: {
230
+ include: {
231
+ type: string;
232
+ items: {
233
+ type: string;
234
+ };
235
+ };
236
+ exclude: {
237
+ type: string;
238
+ items: {
239
+ type: string;
240
+ };
241
+ };
242
+ };
243
+ };
244
+ };
245
+ };
246
+ })[];
247
+ };
176
248
  target: {
177
249
  type: string;
178
250
  enum: string[];
@@ -375,6 +447,78 @@ export declare const BannerBlock: {
375
447
  };
376
448
  };
377
449
  };
450
+ analyticsEvents: {
451
+ anyOf: ({
452
+ type: string;
453
+ additionalProperties: {
454
+ type: string;
455
+ };
456
+ required: string[];
457
+ properties: {
458
+ name: {
459
+ type: string;
460
+ };
461
+ type: {
462
+ type: string;
463
+ };
464
+ counters: {
465
+ type: string;
466
+ additionalProperties: boolean;
467
+ required: never[];
468
+ properties: {
469
+ include: {
470
+ type: string;
471
+ items: {
472
+ type: string;
473
+ };
474
+ };
475
+ exclude: {
476
+ type: string;
477
+ items: {
478
+ type: string;
479
+ };
480
+ };
481
+ };
482
+ };
483
+ };
484
+ } | {
485
+ type: string;
486
+ items: {
487
+ type: string;
488
+ additionalProperties: {
489
+ type: string;
490
+ };
491
+ required: string[];
492
+ properties: {
493
+ name: {
494
+ type: string;
495
+ };
496
+ type: {
497
+ type: string;
498
+ };
499
+ counters: {
500
+ type: string;
501
+ additionalProperties: boolean;
502
+ required: never[];
503
+ properties: {
504
+ include: {
505
+ type: string;
506
+ items: {
507
+ type: string;
508
+ };
509
+ };
510
+ exclude: {
511
+ type: string;
512
+ items: {
513
+ type: string;
514
+ };
515
+ };
516
+ };
517
+ };
518
+ };
519
+ };
520
+ })[];
521
+ };
378
522
  target: {
379
523
  type: string;
380
524
  enum: string[];
@@ -578,6 +722,78 @@ export declare const BannerCard: {
578
722
  };
579
723
  };
580
724
  };
725
+ analyticsEvents: {
726
+ anyOf: ({
727
+ type: string;
728
+ additionalProperties: {
729
+ type: string;
730
+ };
731
+ required: string[];
732
+ properties: {
733
+ name: {
734
+ type: string;
735
+ };
736
+ type: {
737
+ type: string;
738
+ };
739
+ counters: {
740
+ type: string;
741
+ additionalProperties: boolean;
742
+ required: never[];
743
+ properties: {
744
+ include: {
745
+ type: string;
746
+ items: {
747
+ type: string;
748
+ };
749
+ };
750
+ exclude: {
751
+ type: string;
752
+ items: {
753
+ type: string;
754
+ };
755
+ };
756
+ };
757
+ };
758
+ };
759
+ } | {
760
+ type: string;
761
+ items: {
762
+ type: string;
763
+ additionalProperties: {
764
+ type: string;
765
+ };
766
+ required: string[];
767
+ properties: {
768
+ name: {
769
+ type: string;
770
+ };
771
+ type: {
772
+ type: string;
773
+ };
774
+ counters: {
775
+ type: string;
776
+ additionalProperties: boolean;
777
+ required: never[];
778
+ properties: {
779
+ include: {
780
+ type: string;
781
+ items: {
782
+ type: string;
783
+ };
784
+ };
785
+ exclude: {
786
+ type: string;
787
+ items: {
788
+ type: string;
789
+ };
790
+ };
791
+ };
792
+ };
793
+ };
794
+ };
795
+ })[];
796
+ };
581
797
  target: {
582
798
  type: string;
583
799
  enum: string[];
@@ -426,6 +426,78 @@ export declare const MediaBlock: {
426
426
  };
427
427
  };
428
428
  };
429
+ analyticsEvents: {
430
+ anyOf: ({
431
+ type: string;
432
+ additionalProperties: {
433
+ type: string;
434
+ };
435
+ required: string[];
436
+ properties: {
437
+ name: {
438
+ type: string;
439
+ };
440
+ type: {
441
+ type: string;
442
+ };
443
+ counters: {
444
+ type: string;
445
+ additionalProperties: boolean;
446
+ required: never[];
447
+ properties: {
448
+ include: {
449
+ type: string;
450
+ items: {
451
+ type: string;
452
+ };
453
+ };
454
+ exclude: {
455
+ type: string;
456
+ items: {
457
+ type: string;
458
+ };
459
+ };
460
+ };
461
+ };
462
+ };
463
+ } | {
464
+ type: string;
465
+ items: {
466
+ type: string;
467
+ additionalProperties: {
468
+ type: string;
469
+ };
470
+ required: string[];
471
+ properties: {
472
+ name: {
473
+ type: string;
474
+ };
475
+ type: {
476
+ type: string;
477
+ };
478
+ counters: {
479
+ type: string;
480
+ additionalProperties: boolean;
481
+ required: never[];
482
+ properties: {
483
+ include: {
484
+ type: string;
485
+ items: {
486
+ type: string;
487
+ };
488
+ };
489
+ exclude: {
490
+ type: string;
491
+ items: {
492
+ type: string;
493
+ };
494
+ };
495
+ };
496
+ };
497
+ };
498
+ };
499
+ })[];
500
+ };
429
501
  target: {
430
502
  type: string;
431
503
  enum: string[];
@@ -5,20 +5,23 @@ import { block, setUrlTld } from '../../utils';
5
5
  import { toCommonSize, toCommonView } from './utils';
6
6
  import { LocaleContext } from '../../context/localeContext/localeContext';
7
7
  import { useMetrika } from '../../hooks/useMetrika';
8
+ import { useAnalytics } from '../../hooks';
8
9
  import { Github } from '../../icons';
9
10
  import './Button.css';
10
11
  const b = block('button-block');
11
12
  const Button = (props) => {
12
13
  const handleMetrika = useMetrika();
14
+ const handleAnalytics = useAnalytics();
13
15
  const { lang, tld } = useContext(LocaleContext);
14
- const { className, metrikaGoals, pixelEvents, size = 'l', theme = 'normal', url, img, onClick: onClickOrigin, text } = props, rest = __rest(props, ["className", "metrikaGoals", "pixelEvents", "size", "theme", "url", "img", "onClick", "text"]);
16
+ const { className, metrikaGoals, pixelEvents, analyticsEvents, size = 'l', theme = 'normal', url, img, onClick: onClickOrigin, text } = props, rest = __rest(props, ["className", "metrikaGoals", "pixelEvents", "analyticsEvents", "size", "theme", "url", "img", "onClick", "text"]);
15
17
  const defaultImgPosition = 'left';
16
18
  const onClick = useCallback(() => {
17
19
  handleMetrika({ metrikaGoals, pixelEvents });
20
+ handleAnalytics === null || handleAnalytics === void 0 ? void 0 : handleAnalytics(analyticsEvents);
18
21
  if (onClickOrigin) {
19
22
  onClickOrigin();
20
23
  }
21
- }, [handleMetrika, metrikaGoals, pixelEvents, onClickOrigin]);
24
+ }, [handleMetrika, metrikaGoals, pixelEvents, handleAnalytics, analyticsEvents, onClickOrigin]);
22
25
  const buttonImg = img instanceof Object
23
26
  ? { url: img.url, position: img.position || defaultImgPosition, alt: img.alt }
24
27
  : { url: img, position: defaultImgPosition };
@@ -1,5 +1,6 @@
1
1
  import React, { ReactElement, HTMLAttributeAnchorTarget } from 'react';
2
2
  import { ButtonPixel, CardBaseProps as CardBaseParams, ImageProps, MetrikaGoal, WithChildren } from '../../models';
3
+ import { AnalyticsEventV2 } from '../../models/common';
3
4
  import './CardBase.css';
4
5
  export interface CardBaseProps extends CardBaseParams {
5
6
  className?: string;
@@ -10,6 +11,7 @@ export interface CardBaseProps extends CardBaseParams {
10
11
  target?: HTMLAttributeAnchorTarget;
11
12
  metrikaGoals?: MetrikaGoal;
12
13
  pixelEvents?: ButtonPixel;
14
+ analyticsEvents?: AnalyticsEventV2 | AnalyticsEventV2[];
13
15
  }
14
16
  export interface CardHeaderBaseProps {
15
17
  className?: string;
@@ -3,14 +3,16 @@ import { block } from '../../utils';
3
3
  import BackgroundImage from '../BackgroundImage/BackgroundImage';
4
4
  import RouterLink from '../RouterLink/RouterLink';
5
5
  import { useMetrika } from '../../hooks/useMetrika';
6
+ import { useAnalytics } from '../../hooks';
6
7
  import './CardBase.css';
7
8
  const b = block('card-base-block');
8
9
  const Header = () => null;
9
10
  const Content = () => null;
10
11
  const Footer = () => null;
11
12
  export const Layout = (props) => {
12
- const { className, bodyClassName, metrikaGoals, pixelEvents, contentClassName, children, url, target, border = 'shadow', } = props;
13
+ const { className, bodyClassName, metrikaGoals, pixelEvents, analyticsEvents, contentClassName, children, url, target, border = 'shadow', } = props;
13
14
  const handleMetrika = useMetrika();
15
+ const handleAnalytics = useAnalytics();
14
16
  let header, content, footer, image, headerClass, footerClass;
15
17
  function handleChild(child) {
16
18
  switch (child.type) {
@@ -43,6 +45,7 @@ export const Layout = (props) => {
43
45
  const fullClassName = b({ border }, className);
44
46
  const onClick = () => {
45
47
  handleMetrika({ metrikaGoals, pixelEvents });
48
+ handleAnalytics === null || handleAnalytics === void 0 ? void 0 : handleAnalytics(analyticsEvents);
46
49
  };
47
50
  return url ? (React.createElement(RouterLink, { href: url },
48
51
  React.createElement("a", { href: url, target: target, rel: target === '_blank' ? 'noopener noreferrer' : undefined, className: fullClassName, draggable: false, onDragStart: (e) => e.preventDefault(), onClick: onClick }, cardContent))) : (React.createElement("div", { className: fullClassName }, cardContent));
@@ -1,13 +1,16 @@
1
1
  import React from 'react';
2
2
  import { block } from '../../utils';
3
3
  import { useMetrika } from '../../hooks/useMetrika';
4
+ import { useAnalytics } from '../../hooks';
4
5
  import './HeaderBreadcrumbs.css';
5
6
  const b = block('header-breadcrumbs');
6
7
  export default function HeaderBreadcrumbs(props) {
7
- const { items, metrikaGoals, pixelEvents, theme = 'light', className } = props;
8
+ const { items, metrikaGoals, pixelEvents, analyticsEvents, theme = 'light', className } = props;
8
9
  const handleMetrika = useMetrika();
10
+ const handleAnalytics = useAnalytics();
9
11
  const onClick = () => {
10
12
  handleMetrika({ metrikaGoals, pixelEvents });
13
+ handleAnalytics === null || handleAnalytics === void 0 ? void 0 : handleAnalytics(analyticsEvents);
11
14
  };
12
15
  return (React.createElement("div", { className: b({ theme }, className) }, items.map((item) => (React.createElement("div", { className: b('item'), key: item.url },
13
16
  React.createElement("a", { href: item.url, className: b('text'), onClick: onClick }, item.text))))));
@@ -7,6 +7,7 @@ import BackLink from '../BackLink/BackLink';
7
7
  import { LocaleContext } from '../../context/localeContext/localeContext';
8
8
  import { LocationContext } from '../../context/locationContext/locationContext';
9
9
  import { useMetrika } from '../../hooks/useMetrika';
10
+ import { useAnalytics } from '../../hooks';
10
11
  import './Link.css';
11
12
  const b = block('link-block');
12
13
  const WORD_JOINER_SYM = '\u200b';
@@ -23,14 +24,16 @@ function getArrowSize(size) {
23
24
  }
24
25
  }
25
26
  const LinkBlock = (props) => {
26
- const { text, url, arrow, metrikaGoals, pixelEvents, theme = 'file-link', colorTheme = 'light', textSize = 'm', className, target, children, } = props;
27
+ const { text, url, arrow, metrikaGoals, pixelEvents, analyticsEvents, theme = 'file-link', colorTheme = 'light', textSize = 'm', className, target, children, } = props;
27
28
  const handleMetrika = useMetrika();
29
+ const handleAnalytics = useAnalytics();
28
30
  const { hostname } = useContext(LocationContext);
29
31
  const { tld } = useContext(LocaleContext);
30
32
  const href = setUrlTld(props.url, tld);
31
33
  const defaultTextSize = theme === 'back' ? 'l' : 'm';
32
34
  const onClick = () => {
33
35
  handleMetrika({ metrikaGoals, pixelEvents });
36
+ handleAnalytics === null || handleAnalytics === void 0 ? void 0 : handleAnalytics(analyticsEvents);
34
37
  };
35
38
  const getLinkByType = () => {
36
39
  switch (theme) {
@@ -7,7 +7,7 @@ import YoutubeBlock from '../VideoBlock/VideoBlock';
7
7
  import './Media.css';
8
8
  const b = block('Media');
9
9
  export const Media = (props) => {
10
- const { image, video, youtube, dataLens, color, height, previewImg, parallax = false, metrika, } = props;
10
+ const { image, video, youtube, dataLens, color, height, previewImg, parallax = false, metrika, analyticsEvents, } = props;
11
11
  const { className, imageClassName, videoClassName, youtubeClassName, playVideo = true, isBackground, playButton, customBarControlsClassName, } = props;
12
12
  const [hasVideoFallback, setHasVideoFallback] = useState(false);
13
13
  const content = useMemo(() => {
@@ -16,7 +16,7 @@ export const Media = (props) => {
16
16
  result.push(React.createElement(Image, { key: "image", parallax: parallax, image: image, height: height, imageClassName: imageClassName, isBackground: isBackground, video: video, hasVideoFallback: hasVideoFallback }));
17
17
  }
18
18
  if (video) {
19
- result.push(React.createElement(Video, { key: "video", video: video, videoClassName: videoClassName, height: height, metrika: metrika, playVideo: playVideo, previewImg: previewImg, playButton: playButton, customBarControlsClassName: customBarControlsClassName, hasVideoFallback: hasVideoFallback, setHasVideoFallback: setHasVideoFallback }));
19
+ result.push(React.createElement(Video, { key: "video", video: video, videoClassName: videoClassName, height: height, metrika: metrika, analyticsEvents: analyticsEvents, playVideo: playVideo, previewImg: previewImg, playButton: playButton, customBarControlsClassName: customBarControlsClassName, hasVideoFallback: hasVideoFallback, setHasVideoFallback: setHasVideoFallback }));
20
20
  }
21
21
  if (youtube) {
22
22
  result = (React.createElement(YoutubeBlock, { className: b('youtube', youtubeClassName), record: youtube, attributes: { color: 'white', rel: '0' }, previewImg: previewImg, height: height }));
@@ -37,6 +37,7 @@ export const Media = (props) => {
37
37
  hasVideoFallback,
38
38
  videoClassName,
39
39
  metrika,
40
+ analyticsEvents,
40
41
  playVideo,
41
42
  previewImg,
42
43
  playButton,
@@ -6,7 +6,7 @@ import { block } 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, previewImg, playButton: commonPlayButton, customBarControlsClassName, videoClassName, playVideo, setHasVideoFallback, hasVideoFallback, } = props;
9
+ const { video, height, metrika, analyticsEvents, previewImg, playButton: commonPlayButton, customBarControlsClassName, videoClassName, playVideo, setHasVideoFallback, hasVideoFallback, } = props;
10
10
  const ref = useRef(null);
11
11
  useEffect(() => {
12
12
  if (ref && ref.current) {
@@ -29,16 +29,17 @@ const Video = (props) => {
29
29
  }, [playVideo, video, setHasVideoFallback]);
30
30
  const reactPlayerBlock = useMemo(() => {
31
31
  const { src, loop, controls, muted, autoplay = true, elapsedTime, playButton } = video;
32
- return (React.createElement(ReactPlayerBlock, { className: b('react-player', videoClassName), src: src, previewImgUrl: previewImg, loop: Boolean(loop), controls: controls, muted: muted, autoplay: autoplay && playVideo, elapsedTime: elapsedTime, playButton: playButton || commonPlayButton, customBarControlsClassName: customBarControlsClassName, metrika: metrika, height: height }));
32
+ return (React.createElement(ReactPlayerBlock, { className: b('react-player', videoClassName), src: src, previewImgUrl: previewImg, loop: Boolean(loop), controls: controls, muted: muted, autoplay: autoplay && playVideo, elapsedTime: elapsedTime, playButton: playButton || commonPlayButton, customBarControlsClassName: customBarControlsClassName, metrika: metrika, analyticsEvents: analyticsEvents, height: height }));
33
33
  }, [
34
34
  video,
35
- height,
36
35
  videoClassName,
37
36
  previewImg,
38
37
  playVideo,
39
38
  commonPlayButton,
40
39
  customBarControlsClassName,
41
40
  metrika,
41
+ analyticsEvents,
42
+ height,
42
43
  ]);
43
44
  const defaultVideoBlock = useMemo(() => {
44
45
  return video.src.length && !hasVideoFallback ? (React.createElement("div", { className: b('wrap', videoClassName), style: { height } },
@@ -9,6 +9,7 @@ import { VideoContext } from '../../context/videoContext';
9
9
  import { MetrikaContext } from '../../context/metrikaContext';
10
10
  import { MobileContext } from '../../context/mobileContext';
11
11
  import { PlayVideo } from '../../icons';
12
+ import { useAnalytics } from '../../hooks';
12
13
  import './ReactPlayer.css';
13
14
  const b = block('ReactPlayer');
14
15
  const FPS = 60;
@@ -16,7 +17,7 @@ const FPS = 60;
16
17
  export const ReactPlayerBlock = React.forwardRef((props, originRef) => {
17
18
  const isMobile = useContext(MobileContext);
18
19
  const { metrika } = useContext(MetrikaContext);
19
- const { src, previewImgUrl, loop = false, controls = MediaVideoControlsType.Default, muted: initiallyMuted = false, elapsedTime, playButton, className, customBarControlsClassName, showPreview, onClickPreview, metrika: videoMetrika, height, } = props;
20
+ const { src, previewImgUrl, loop = false, controls = MediaVideoControlsType.Default, muted: initiallyMuted = false, elapsedTime, playButton, className, customBarControlsClassName, showPreview, onClickPreview, metrika: videoMetrika, analyticsEvents, height, } = props;
20
21
  const { type = PlayButtonType.Default, theme = PlayButtonThemes.Blue, text, className: buttonClassName, } = playButton || {};
21
22
  const autoPlay = Boolean(!isMobile && !previewImgUrl && props.autoplay);
22
23
  const mute = initiallyMuted || autoPlay;
@@ -31,6 +32,7 @@ export const ReactPlayerBlock = React.forwardRef((props, originRef) => {
31
32
  const [started, setStarted] = useState(autoPlay);
32
33
  const [paused, setPaused] = useState(false);
33
34
  const [ended, setEnded] = useState(false);
35
+ const handleAnalytics = useAnalytics();
34
36
  useImperativeHandle(originRef, () => ({
35
37
  pause: () => setIsPlaying(false),
36
38
  }));
@@ -79,6 +81,8 @@ export const ReactPlayerBlock = React.forwardRef((props, originRef) => {
79
81
  window.removeEventListener('resize', updateSize);
80
82
  };
81
83
  }, []);
84
+ const playEvents = useMemo(() => analyticsEvents === null || analyticsEvents === void 0 ? void 0 : analyticsEvents.filter((e) => e.type === 'play'), [analyticsEvents]);
85
+ const stopEvents = useMemo(() => analyticsEvents === null || analyticsEvents === void 0 ? void 0 : analyticsEvents.filter((e) => e.type === 'stop'), [analyticsEvents]);
82
86
  const playIcon = useMemo(() => {
83
87
  let playButtonContent;
84
88
  switch (type) {
@@ -104,12 +108,27 @@ export const ReactPlayerBlock = React.forwardRef((props, originRef) => {
104
108
  metrika.reachGoals(goal, counterName);
105
109
  }
106
110
  }
111
+ if (handleAnalytics && analyticsEvents) {
112
+ const events = isMuted ? playEvents : stopEvents;
113
+ if (events) {
114
+ handleAnalytics(events);
115
+ }
116
+ }
107
117
  if (isMuted) {
108
118
  setProps({ playingVideoRef: ref.current });
109
119
  }
110
120
  // In order to the progress bar to update (equals 0) before displaying
111
121
  setTimeout(() => setMuted(!isMuted), 0);
112
- }, [playerRef, setProps, videoMetrika, metrika]);
122
+ }, [
123
+ playerRef,
124
+ metrika,
125
+ videoMetrika,
126
+ handleAnalytics,
127
+ analyticsEvents,
128
+ playEvents,
129
+ stopEvents,
130
+ setProps,
131
+ ]);
113
132
  const handleClick = useCallback(() => changeMute(muted), [changeMute, muted]);
114
133
  const handleClickPreview = useCallback(() => {
115
134
  setIsPlaying(true);
@@ -120,7 +139,12 @@ export const ReactPlayerBlock = React.forwardRef((props, originRef) => {
120
139
  metrika.reachGoals(play, counterName);
121
140
  }
122
141
  }
123
- }, [onClickPreview, setIsPlaying, videoMetrika, metrika]);
142
+ if (handleAnalytics && analyticsEvents) {
143
+ if (playEvents) {
144
+ handleAnalytics(playEvents);
145
+ }
146
+ }
147
+ }, [onClickPreview, metrika, videoMetrika, handleAnalytics, analyticsEvents, playEvents]);
124
148
  const onPause = useCallback(() => {
125
149
  // For support correct state for youtube
126
150
  setIsPlaying(false);
@@ -1,4 +1,5 @@
1
1
  import { PixelEvent } from '../../models';
2
+ import { AnalyticsEventV2 } from '../../models/common';
2
3
  export declare const YANDEX_FORM_ORIGIN = "https://forms.yandex.ru";
3
4
  export interface YandexFormProps {
4
5
  id: number | string;
@@ -14,6 +15,7 @@ export interface YandexFormProps {
14
15
  onLoad?: () => void;
15
16
  metrikaGoals?: string | string[];
16
17
  pixelEvents?: string | string[] | PixelEvent | PixelEvent[];
18
+ analyticsEvents?: AnalyticsEventV2 | AnalyticsEventV2[];
17
19
  }
18
20
  declare const YandexForm: (props: YandexFormProps) => JSX.Element;
19
21
  export default YandexForm;
@@ -4,15 +4,17 @@ import { LocaleContext } from '../../context/localeContext';
4
4
  import { MobileContext } from '../../context/mobileContext';
5
5
  import { block } from '../../utils';
6
6
  import { useMetrika } from '../../hooks/useMetrika';
7
+ import { useAnalytics } from '../..//hooks';
7
8
  export const YANDEX_FORM_ORIGIN = 'https://forms.yandex.ru';
8
9
  const CONTAINER_ID = 'pc-yandex-form-container';
9
10
  const b = block('yandex-form');
10
11
  const YandexForm = (props) => {
11
- const { onLoad, id, params, className, theme, containerId = CONTAINER_ID, headerHeight = HEADER_HEIGHT, onSubmit, metrikaGoals, pixelEvents, customFormOrigin, } = props;
12
+ const { onLoad, id, params, className, theme, containerId = CONTAINER_ID, headerHeight = HEADER_HEIGHT, onSubmit, metrikaGoals, pixelEvents, analyticsEvents, customFormOrigin, } = props;
12
13
  const formContainerRef = useRef(null);
13
14
  const iframeRef = useRef();
14
15
  const yaFormOrigin = customFormOrigin || YANDEX_FORM_ORIGIN;
15
16
  const handleMetrika = useMetrika();
17
+ const handleAnalytics = useAnalytics();
16
18
  const isMobile = useContext(MobileContext);
17
19
  const locale = useContext(LocaleContext);
18
20
  const updateFormIframe = useCallback((container) => {
@@ -53,10 +55,19 @@ const YandexForm = (props) => {
53
55
  window.scrollBy(0, top - headerHeight);
54
56
  }
55
57
  handleMetrika({ metrikaGoals, pixelEvents });
58
+ handleAnalytics === null || handleAnalytics === void 0 ? void 0 : handleAnalytics(analyticsEvents);
56
59
  if (onSubmit) {
57
60
  onSubmit();
58
61
  }
59
- }, [handleMetrika, metrikaGoals, pixelEvents, onSubmit, headerHeight]);
62
+ }, [
63
+ handleMetrika,
64
+ metrikaGoals,
65
+ pixelEvents,
66
+ handleAnalytics,
67
+ analyticsEvents,
68
+ onSubmit,
69
+ headerHeight,
70
+ ]);
60
71
  const handleMessage = useCallback(({ origin, data }) => {
61
72
  if (origin !== yaFormOrigin) {
62
73
  return;