@gravity-ui/page-constructor 4.18.1 → 4.19.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 (41) hide show
  1. package/README.md +5 -1
  2. package/build/cjs/components/Media/Media.js +3 -1
  3. package/build/cjs/components/Media/Video/Video.js +3 -2
  4. package/build/cjs/components/ReactPlayer/CustomBarControls.css +45 -24
  5. package/build/cjs/components/ReactPlayer/CustomBarControls.d.ts +3 -2
  6. package/build/cjs/components/ReactPlayer/CustomBarControls.js +29 -17
  7. package/build/cjs/components/ReactPlayer/ReactPlayer.css +2 -16
  8. package/build/cjs/components/ReactPlayer/ReactPlayer.d.ts +1 -0
  9. package/build/cjs/components/ReactPlayer/ReactPlayer.js +19 -14
  10. package/build/cjs/models/constructor-items/common.d.ts +8 -0
  11. package/build/cjs/models/constructor-items/common.js +7 -1
  12. package/build/esm/components/Media/Media.js +3 -1
  13. package/build/esm/components/Media/Video/Video.js +3 -2
  14. package/build/esm/components/ReactPlayer/CustomBarControls.css +45 -24
  15. package/build/esm/components/ReactPlayer/CustomBarControls.d.ts +3 -2
  16. package/build/esm/components/ReactPlayer/CustomBarControls.js +29 -17
  17. package/build/esm/components/ReactPlayer/ReactPlayer.css +2 -16
  18. package/build/esm/components/ReactPlayer/ReactPlayer.d.ts +1 -0
  19. package/build/esm/components/ReactPlayer/ReactPlayer.js +20 -15
  20. package/build/esm/models/constructor-items/common.d.ts +8 -0
  21. package/build/esm/models/constructor-items/common.js +6 -0
  22. package/package.json +1 -1
  23. package/server/models/constructor-items/common.d.ts +8 -0
  24. package/server/models/constructor-items/common.js +7 -1
  25. package/widget/index.js +1 -1
  26. package/build/cjs/icons/MuteSmall.d.ts +0 -2
  27. package/build/cjs/icons/MuteSmall.js +0 -15
  28. package/build/cjs/icons/UnmuteSmall.d.ts +0 -2
  29. package/build/cjs/icons/UnmuteSmall.js +0 -17
  30. package/build/cjs/icons/VideoControlPause.d.ts +0 -2
  31. package/build/cjs/icons/VideoControlPause.js +0 -16
  32. package/build/cjs/icons/VideoControlPlay.d.ts +0 -2
  33. package/build/cjs/icons/VideoControlPlay.js +0 -12
  34. package/build/esm/icons/MuteSmall.d.ts +0 -2
  35. package/build/esm/icons/MuteSmall.js +0 -10
  36. package/build/esm/icons/UnmuteSmall.d.ts +0 -2
  37. package/build/esm/icons/UnmuteSmall.js +0 -12
  38. package/build/esm/icons/VideoControlPause.d.ts +0 -2
  39. package/build/esm/icons/VideoControlPause.js +0 -11
  40. package/build/esm/icons/VideoControlPlay.d.ts +0 -2
  41. package/build/esm/icons/VideoControlPlay.js +0 -7
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  When creating pages, component-based approach is used: a page is built using a set of ready-made blocks that can be placed in any order. Each block has a certain type and set of input data parameters.
8
8
 
9
- For the format of input data and list of available blocks, see the [documentation](https://preview.yandexcloud.dev/page-constructor/?path=/story/information--blocks).
9
+ For the format of input data and list of available blocks, see the [documentation](https://preview.yandexcloud.dev/page-constructor/?path=/docs/documentation-blocks--docs).
10
10
 
11
11
  ## Install
12
12
 
@@ -14,6 +14,10 @@ For the format of input data and list of available blocks, see the [documentatio
14
14
  npm install @gravity-ui/page-constructor
15
15
  ```
16
16
 
17
+ ## Required dependencies
18
+
19
+ Please note that to start using the package, your project must also have the following installed: `@doc-tools/transform`, `@gravity-ui/uikit`, `react`. Check out the `peerDependencies` section of `package.json` for accurate information.
20
+
17
21
  ### Getting started
18
22
 
19
23
  The page constructor is imported as a React component. To make sure it runs properly, wrap it in `PageConstructorProvider`:
@@ -11,7 +11,7 @@ const Image_1 = tslib_1.__importDefault(require("./Image/Image"));
11
11
  const Video_1 = tslib_1.__importDefault(require("./Video/Video"));
12
12
  const b = (0, utils_1.block)('Media');
13
13
  const Media = (props) => {
14
- const { image, video, youtube, dataLens, color, height, previewImg, parallax = false, metrika, fullscreen, analyticsEvents, className, imageClassName, videoClassName, youtubeClassName, playVideo = true, isBackground, playButton, customBarControlsClassName, qa, } = props;
14
+ const { image, video, youtube, dataLens, color, height, previewImg, parallax = false, metrika, fullscreen, analyticsEvents, className, imageClassName, videoClassName, youtubeClassName, playVideo = true, isBackground, playButton, customBarControlsClassName, qa, ratio, } = props;
15
15
  const [hasVideoFallback, setHasVideoFallback] = (0, react_1.useState)(false);
16
16
  const qaAttributes = (0, utils_1.getQaAttrubutes)(qa, 'video');
17
17
  const content = (0, react_1.useMemo)(() => {
@@ -33,6 +33,7 @@ const Media = (props) => {
33
33
  customBarControlsClassName,
34
34
  hasVideoFallback,
35
35
  setHasVideoFallback,
36
+ ratio,
36
37
  };
37
38
  if (fullscreen) {
38
39
  result.push(react_1.default.createElement(FullscreenVideo_1.default, Object.assign({}, videoProps, { qa: qaAttributes.video })));
@@ -68,6 +69,7 @@ const Media = (props) => {
68
69
  previewImg,
69
70
  playButton,
70
71
  customBarControlsClassName,
72
+ ratio,
71
73
  youtubeClassName,
72
74
  ]);
73
75
  return (react_1.default.createElement("div", { className: b(null, className), style: { backgroundColor: color }, "data-qa": qa }, content));
@@ -8,7 +8,7 @@ const ReactPlayer_1 = tslib_1.__importDefault(require("../../ReactPlayer/ReactPl
8
8
  const utils_2 = require("./utils");
9
9
  const b = (0, utils_1.block)('media-component-video');
10
10
  const Video = (props) => {
11
- const { video, height, metrika, analyticsEvents, previewImg, playButton: commonPlayButton, customBarControlsClassName, videoClassName, playVideo, setHasVideoFallback, hasVideoFallback, qa, } = props;
11
+ const { video, height, metrika, analyticsEvents, previewImg, playButton: commonPlayButton, customBarControlsClassName, videoClassName, playVideo, setHasVideoFallback, hasVideoFallback, qa, ratio, } = props;
12
12
  const qaAttributes = (0, utils_1.getQaAttrubutes)(qa, 'source');
13
13
  const ref = (0, react_1.useRef)(null);
14
14
  (0, react_1.useEffect)(() => {
@@ -32,7 +32,7 @@ const Video = (props) => {
32
32
  }, [playVideo, video, setHasVideoFallback]);
33
33
  const reactPlayerBlock = (0, react_1.useMemo)(() => {
34
34
  const { src, loop, controls, muted, autoplay = true, elapsedTime, playButton, ariaLabel, customControlsOptions, } = video;
35
- return (react_1.default.createElement(ReactPlayer_1.default, { 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, ariaLabel: ariaLabel, customControlsOptions: customControlsOptions }));
35
+ return (react_1.default.createElement(ReactPlayer_1.default, { 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, ariaLabel: ariaLabel, customControlsOptions: customControlsOptions, ratio: ratio }));
36
36
  }, [
37
37
  video,
38
38
  height,
@@ -43,6 +43,7 @@ const Video = (props) => {
43
43
  customBarControlsClassName,
44
44
  metrika,
45
45
  analyticsEvents,
46
+ ratio,
46
47
  ]);
47
48
  const defaultVideoBlock = (0, react_1.useMemo)(() => {
48
49
  return video.src.length && !hasVideoFallback ? (react_1.default.createElement("div", { className: b('wrap', videoClassName), style: { height }, "data-qa": qaAttributes.default },
@@ -1,36 +1,43 @@
1
+ .pc-CustomBarControls__button_type_with-play-pause-button {
2
+ box-shadow: 0px 4px 24px var(--pc-color-sfx-shadow), 0px 2px 8px var(--pc-color-sfx-shadow);
3
+ }
4
+
5
+ .pc-CustomBarControls__button_type_with-play-pause-button:hover {
6
+ box-shadow: 0px 4px 24px var(--g-color-sfx-shadow), 0px 2px 8px var(--g-color-sfx-shadow);
7
+ cursor: pointer;
8
+ }
9
+
1
10
  /* use this for style redefinitions to awoid problems with
2
11
  unpredictable css rules order in build */
3
12
  .pc-CustomBarControls__wrapper {
4
13
  position: absolute;
5
14
  bottom: 0;
15
+ opacity: 0;
16
+ transition: opacity 300ms ease 3s;
17
+ }
18
+ .pc-CustomBarControls__wrapper_shown {
19
+ opacity: 1;
20
+ transition: opacity 0s ease 0s;
6
21
  }
7
22
  .pc-CustomBarControls__wrapper_type_with-play-pause-button {
8
- width: 100%;
9
- padding: 20px;
23
+ gap: 8px;
24
+ padding: 8px;
25
+ }
26
+ .pc-CustomBarControls__wrapper_positioning_left, .pc-CustomBarControls__wrapper_positioning_right, .pc-CustomBarControls__wrapper_positioning_center {
10
27
  display: flex;
11
- gap: 20px;
28
+ width: 100%;
29
+ }
30
+ .pc-CustomBarControls__wrapper_positioning_right {
31
+ flex-direction: row-reverse;
32
+ }
33
+ .pc-CustomBarControls__wrapper_positioning_center {
34
+ justify-content: center;
12
35
  }
13
36
  .pc-CustomBarControls__button {
14
37
  border: 0;
15
38
  padding: 0;
16
39
  cursor: pointer;
17
40
  }
18
- .pc-CustomBarControls__button_type_with-play-pause-button {
19
- opacity: 0.9;
20
- background-color: transparent;
21
- transition: opacity 300ms ease 3s;
22
- }
23
- .pc-CustomBarControls__button_type_with-play-pause-button:hover, .pc-CustomBarControls__button_type_with-play-pause-button:focus {
24
- opacity: 1;
25
- }
26
- .pc-CustomBarControls__button_type_with-play-pause-button:focus {
27
- outline: 1px solid var(--g-color-line-light);
28
- outline-offset: 2px;
29
- border-radius: 4px;
30
- }
31
- .pc-CustomBarControls__button_type_with-play-pause-button:focus:not(:focus-visible) {
32
- outline: none;
33
- }
34
41
  .pc-CustomBarControls__button_type_with-mute-button {
35
42
  border-radius: 50%;
36
43
  display: flex;
@@ -53,15 +60,29 @@ unpredictable css rules order in build */
53
60
  .pc-CustomBarControls__button_type_with-mute-button:focus:not(:focus-visible) {
54
61
  outline: none;
55
62
  }
56
- .pc-CustomBarControls__play-icon {
57
- height: 24px;
58
- width: 24px;
63
+ .pc-CustomBarControls__button_type_with-play-pause-button {
64
+ width: 42px;
65
+ height: 42px;
66
+ border-radius: 50%;
67
+ background: var(--g-color-base-background);
68
+ }
69
+ .pc-CustomBarControls__button_type_with-play-pause-button:focus {
70
+ outline: 2px solid var(--g-color-line-misc);
71
+ }
72
+ .pc-CustomBarControls__button_type_with-play-pause-button:focus:not(:focus-visible) {
73
+ outline: none;
74
+ }
75
+ .pc-CustomBarControls__play-icon_type_with-play-pause-button {
76
+ height: 16px;
77
+ width: 16px;
78
+ color: var(--g-color-base-neutral-heavy);
59
79
  }
60
80
  .pc-CustomBarControls__mute-icon_type_with-mute-button {
61
81
  height: 22px;
62
82
  width: 32px;
63
83
  }
64
84
  .pc-CustomBarControls__mute-icon_type_with-play-pause-button {
65
- height: 24px;
66
- width: 24px;
85
+ height: 16px;
86
+ width: 16px;
87
+ color: var(--g-color-base-neutral-heavy);
67
88
  }
@@ -1,15 +1,16 @@
1
1
  import React from 'react';
2
- import { ClassNameProps, CustomControlsType } from '../../models';
2
+ import { ClassNameProps, CustomControlsOptions, CustomControlsType } from '../../models';
3
3
  interface MuteConfigProps {
4
4
  isMuted: boolean;
5
5
  changeMute: (event: React.MouseEvent) => void;
6
6
  }
7
- export interface CustomBarControlsProps extends ClassNameProps {
7
+ export interface CustomBarControlsProps extends ClassNameProps, CustomControlsOptions {
8
8
  mute?: MuteConfigProps;
9
9
  elapsedTimePercent?: number;
10
10
  type?: CustomControlsType;
11
11
  isPaused?: boolean;
12
12
  onPlayClick?: () => void;
13
+ shown?: boolean;
13
14
  }
14
15
  declare const CustomBarControls: (props: CustomBarControlsProps) => JSX.Element;
15
16
  export default CustomBarControls;
@@ -2,43 +2,55 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const react_1 = tslib_1.__importStar(require("react"));
5
+ const icons_1 = require("@gravity-ui/icons");
5
6
  const uikit_1 = require("@gravity-ui/uikit");
6
7
  const Mute_1 = require("../../icons/Mute");
7
- const MuteSmall_1 = require("../../icons/MuteSmall");
8
8
  const Unmute_1 = require("../../icons/Unmute");
9
- const UnmuteSmall_1 = require("../../icons/UnmuteSmall");
10
- const VideoControlPause_1 = require("../../icons/VideoControlPause");
11
- const VideoControlPlay_1 = require("../../icons/VideoControlPlay");
12
9
  const models_1 = require("../../models");
13
10
  const utils_1 = require("../../utils");
14
11
  const CircleProgress_1 = tslib_1.__importDefault(require("./CircleProgress"));
15
12
  const i18n_1 = tslib_1.__importDefault(require("./i18n"));
16
13
  const b = (0, utils_1.block)('CustomBarControls');
14
+ const playIconsMap = {
15
+ [models_1.CustomControlsType.WithMuteButton]: null,
16
+ [models_1.CustomControlsType.WithPlayPauseButton]: icons_1.Play,
17
+ };
18
+ const pauseIconsMap = {
19
+ [models_1.CustomControlsType.WithMuteButton]: null,
20
+ [models_1.CustomControlsType.WithPlayPauseButton]: icons_1.Pause,
21
+ };
22
+ const muteIconsMap = {
23
+ [models_1.CustomControlsType.WithMuteButton]: Mute_1.Mute,
24
+ [models_1.CustomControlsType.WithPlayPauseButton]: icons_1.VolumeLow,
25
+ };
26
+ const unmuteIconsMap = {
27
+ [models_1.CustomControlsType.WithMuteButton]: Unmute_1.Unmute,
28
+ [models_1.CustomControlsType.WithPlayPauseButton]: icons_1.VolumeXmark,
29
+ };
17
30
  const CustomBarControls = (props) => {
18
- const { mute, elapsedTimePercent = 0, className, type = models_1.CustomControlsType.WithMuteButton, isPaused, onPlayClick, } = props;
19
- const muteIcon = (0, react_1.useMemo)(() => {
20
- return type === models_1.CustomControlsType.WithMuteButton ? Mute_1.Mute : MuteSmall_1.MuteSmall;
21
- }, [type]);
22
- const unmuteIcon = (0, react_1.useMemo)(() => {
23
- return type === models_1.CustomControlsType.WithMuteButton ? Unmute_1.Unmute : UnmuteSmall_1.UnmuteSmall;
24
- }, [type]);
31
+ const { mute, elapsedTimePercent = 0, className, type = models_1.CustomControlsType.WithMuteButton, isPaused, onPlayClick, muteButtonShown: isMuteButtonShown = true, shown, positioning, } = props;
32
+ const muteIcon = muteIconsMap[type];
33
+ const unmuteIcon = unmuteIconsMap[type];
34
+ const playIcon = playIconsMap[type];
35
+ const pauseIcon = pauseIconsMap[type];
25
36
  const muteButton = (0, react_1.useMemo)(() => {
26
- if (!mute) {
37
+ if (!mute || !isMuteButtonShown) {
27
38
  return null;
28
39
  }
29
40
  const { isMuted, changeMute } = mute;
30
41
  return (react_1.default.createElement("button", { className: b('button', { type }), onClick: changeMute, "aria-label": (0, i18n_1.default)(isMuted ? 'unmute' : 'mute') },
31
42
  react_1.default.createElement(uikit_1.Icon, { data: isMuted ? unmuteIcon : muteIcon, className: b('mute-icon', { type }) }),
32
43
  type === models_1.CustomControlsType.WithMuteButton && !isMuted && (react_1.default.createElement(CircleProgress_1.default, { elapsedTime: elapsedTimePercent, strokeWidth: 5 }))));
33
- }, [elapsedTimePercent, mute, muteIcon, type, unmuteIcon]);
44
+ }, [elapsedTimePercent, isMuteButtonShown, mute, muteIcon, type, unmuteIcon]);
34
45
  const playPauseButton = (0, react_1.useMemo)(() => {
35
- if (type !== models_1.CustomControlsType.WithPlayPauseButton) {
46
+ const icon = isPaused ? playIcon : pauseIcon;
47
+ if (type === models_1.CustomControlsType.WithMuteButton || !icon) {
36
48
  return null;
37
49
  }
38
50
  return (react_1.default.createElement("button", { onClick: onPlayClick, className: b('button', { type }), "aria-label": (0, i18n_1.default)(isPaused ? 'play' : 'pause') },
39
- react_1.default.createElement(uikit_1.Icon, { data: isPaused ? VideoControlPlay_1.VideoControlPlay : VideoControlPause_1.VideoControlPause, className: b('play-icon') })));
40
- }, [isPaused, onPlayClick, type]);
41
- return (react_1.default.createElement("div", { className: b('wrapper', { type }, className) },
51
+ react_1.default.createElement(uikit_1.Icon, { data: icon, className: b('play-icon', { type }) })));
52
+ }, [isPaused, onPlayClick, type, playIcon, pauseIcon]);
53
+ return (react_1.default.createElement("div", { className: b('wrapper', { type, shown, positioning }, className) },
42
54
  playPauseButton,
43
55
  muteButton));
44
56
  };
@@ -46,14 +46,8 @@ unpredictable css rules order in build */
46
46
  .pc-ReactPlayer__icon {
47
47
  margin-left: 6px;
48
48
  }
49
- .pc-ReactPlayer:hover .pc-ReactPlayer__custom-bar-controls {
50
- opacity: 1;
51
- transition: opacity 300ms ease 0s;
52
- }
53
- .pc-ReactPlayer_started.pc-ReactPlayer_controls_custom.pc-ReactPlayer_hovered::before {
54
- opacity: 1;
55
- }
56
- .pc-ReactPlayer_started.pc-ReactPlayer_controls_custom::before {
49
+ .pc-ReactPlayer_controls_custom::before {
50
+ display: none;
57
51
  position: absolute;
58
52
  width: 100%;
59
53
  height: 100%;
@@ -62,14 +56,6 @@ unpredictable css rules order in build */
62
56
  opacity: 0;
63
57
  transition: opacity 300ms;
64
58
  }
65
- .pc-ReactPlayer__custom-bar-controls {
66
- opacity: 0;
67
- transition: opacity 300ms ease 3s;
68
- }
69
- .pc-ReactPlayer__custom-bar-controls_muted {
70
- opacity: 1;
71
- transition: opacity 0s ease 0s;
72
- }
73
59
  @media only screen and (max-width: 577px) {
74
60
  .pc-ReactPlayer__button_text {
75
61
  font-size: 20px;
@@ -8,6 +8,7 @@ export interface ReactPlayerBlockProps extends Omit<MediaVideoProps, 'loop' | 's
8
8
  showPreview?: boolean;
9
9
  onClickPreview?: () => void;
10
10
  height?: number;
11
+ ratio?: number;
11
12
  children?: React.ReactNode;
12
13
  }
13
14
  export declare const ReactPlayerBlock: React.ForwardRefExoticComponent<ReactPlayerBlockProps & React.RefAttributes<ReactPlayerBlockHandler>>;
@@ -22,9 +22,9 @@ const FPS = 60;
22
22
  exports.ReactPlayerBlock = react_1.default.forwardRef((props, originRef) => {
23
23
  const isMobile = (0, react_1.useContext)(mobileContext_1.MobileContext);
24
24
  const { metrika } = (0, react_1.useContext)(metrikaContext_1.MetrikaContext);
25
- const { src, previewImgUrl, loop = false, controls = models_1.MediaVideoControlsType.Default, customControlsOptions = {}, muted: initiallyMuted = false, elapsedTime, playButton, className, customBarControlsClassName, showPreview, onClickPreview, metrika: videoMetrika, analyticsEvents, height, ariaLabel, } = props;
25
+ const { src, previewImgUrl, loop = false, controls = models_1.MediaVideoControlsType.Default, customControlsOptions = {}, muted: initiallyMuted = false, elapsedTime, playButton, className, customBarControlsClassName, showPreview, onClickPreview, metrika: videoMetrika, analyticsEvents, height, ariaLabel, ratio, } = props;
26
26
  const { type = models_1.PlayButtonType.Default, theme = models_1.PlayButtonThemes.Blue, text, className: buttonClassName, } = playButton || {};
27
- const { type: customControlsType = models_1.CustomControlsType.WithMuteButton } = customControlsOptions;
27
+ const { type: customControlsType = models_1.CustomControlsType.WithMuteButton, muteButtonShown, positioning = models_1.CustomControlsButtonPositioning.Center, } = customControlsOptions;
28
28
  const autoPlay = Boolean(!isMobile && !previewImgUrl && props.autoplay);
29
29
  const mute = initiallyMuted || autoPlay;
30
30
  const { playingVideoRef, setProps } = (0, react_1.useContext)(videoContext_1.VideoContext);
@@ -62,10 +62,10 @@ exports.ReactPlayerBlock = react_1.default.forwardRef((props, originRef) => {
62
62
  }
63
63
  }, [showPreview, playerRef]);
64
64
  (0, react_1.useEffect)(() => {
65
- if (playerRef) {
65
+ if (playerRef && !started) {
66
66
  setIsPlaying(autoPlay);
67
67
  }
68
- }, [autoPlay, playerRef]);
68
+ }, [autoPlay, playerRef, started]);
69
69
  (0, react_1.useEffect)(() => setMuted(mute), [mute]);
70
70
  (0, react_1.useEffect)(() => {
71
71
  if (!started && isPlaying) {
@@ -87,7 +87,7 @@ exports.ReactPlayerBlock = react_1.default.forwardRef((props, originRef) => {
87
87
  parseFloat(paddingLeft) -
88
88
  parseFloat(paddingRight);
89
89
  setWidth(newWidth);
90
- setCurrentHeight(Math.floor(getHeight(newWidth)));
90
+ setCurrentHeight(Math.floor(getHeight(newWidth, ratio)));
91
91
  }
92
92
  }, 200);
93
93
  updateSize();
@@ -95,7 +95,7 @@ exports.ReactPlayerBlock = react_1.default.forwardRef((props, originRef) => {
95
95
  return () => {
96
96
  window.removeEventListener('resize', updateSize);
97
97
  };
98
- }, []);
98
+ }, [ratio]);
99
99
  const playEvents = (0, react_1.useMemo)(() => eventsArray === null || eventsArray === void 0 ? void 0 : eventsArray.filter((e) => e.type === models_1.PredefinedEventTypes.Play), [eventsArray]);
100
100
  const stopEvents = (0, react_1.useMemo)(() => eventsArray === null || eventsArray === void 0 ? void 0 : eventsArray.filter((e) => e.type === models_1.PredefinedEventTypes.Stop), [eventsArray]);
101
101
  const playIcon = (0, react_1.useMemo)(() => {
@@ -114,7 +114,7 @@ exports.ReactPlayerBlock = react_1.default.forwardRef((props, originRef) => {
114
114
  const changeMute = (0, react_1.useCallback)((isMuted) => {
115
115
  if (isMuted &&
116
116
  playerRef &&
117
- customControlsType !== models_1.CustomControlsType.WithPlayPauseButton) {
117
+ customControlsType === models_1.CustomControlsType.WithMuteButton) {
118
118
  playerRef.seekTo(0);
119
119
  setPlayedPercent(0);
120
120
  }
@@ -156,7 +156,7 @@ exports.ReactPlayerBlock = react_1.default.forwardRef((props, originRef) => {
156
156
  const onPause = (0, react_1.useCallback)(() => {
157
157
  // For support correct state for youtube
158
158
  if (controls !== models_1.MediaVideoControlsType.Custom ||
159
- customControlsType === models_1.CustomControlsType.WithPlayPauseButton) {
159
+ customControlsType !== models_1.CustomControlsType.WithMuteButton) {
160
160
  setIsPlaying(false);
161
161
  }
162
162
  }, [controls, customControlsType]);
@@ -213,18 +213,23 @@ exports.ReactPlayerBlock = react_1.default.forwardRef((props, originRef) => {
213
213
  }, [changeMute, customControlsType, muted, onPlayClick]);
214
214
  const onFocusIn = (0, react_1.useCallback)(() => setHovered(true), []);
215
215
  const onFocusOut = (0, react_1.useCallback)(() => setHovered(false), []);
216
- return (react_1.default.createElement("div", { className: b({ wrapper: !currentHeight, controls, started, hovered }, className), ref: ref, onClick: handleClick, onMouseEnter: onFocusIn, onMouseLeave: onFocusOut, onFocus: onFocusIn, onBlur: onFocusOut }, isMounted ? (react_1.default.createElement(react_1.Fragment, null,
217
- react_1.default.createElement(react_player_1.default, { className: b('player'), url: videoSrc, muted: muted, controls: controls === models_1.MediaVideoControlsType.Default, height: currentHeight || '100%', width: width || '100%', light: previewImgUrl, playing: isPlaying, playIcon: playIcon, progressInterval: FPS, onClickPreview: handleClickPreview, onStart: onStart, onReady: setPlayerRef, onPlay: onPlay, onPause: onPause, onProgress: onProgress, onEnded: onEnded, "aria-label": ariaLabel }),
218
- controls === models_1.MediaVideoControlsType.Custom && started && (react_1.default.createElement(CustomBarControls_1.default, { className: b('custom-bar-controls', { muted }, customBarControlsClassName), mute: {
216
+ return (react_1.default.createElement("div", { className: b({
217
+ wrapper: !currentHeight,
218
+ controls,
219
+ }, className), ref: ref, onClick: handleClick, onMouseEnter: onFocusIn, onMouseLeave: onFocusOut, onFocus: onFocusIn, onBlur: onFocusOut }, isMounted ? (react_1.default.createElement(react_1.Fragment, null,
220
+ react_1.default.createElement(react_player_1.default, { className: b('player'), url: videoSrc, muted: muted, controls: controls === models_1.MediaVideoControlsType.Default, height: currentHeight || '100%', width: width || '100%', light: previewImgUrl, playing: isPlaying, playIcon: playIcon, progressInterval: FPS, onClickPreview: handleClickPreview, onStart: onStart, onReady: setPlayerRef, onPlay: onPlay, onPause: autoPlay && customControlsType !== models_1.CustomControlsType.WithMuteButton
221
+ ? undefined
222
+ : onPause, onProgress: onProgress, onEnded: onEnded, "aria-label": ariaLabel }),
223
+ controls === models_1.MediaVideoControlsType.Custom && (react_1.default.createElement(CustomBarControls_1.default, { className: customBarControlsClassName, mute: {
219
224
  isMuted: muted,
220
225
  changeMute: (event) => {
221
226
  event.stopPropagation();
222
227
  changeMute(muted);
223
228
  },
224
- }, elapsedTimePercent: playedPercent, type: customControlsType, isPaused: !isPlaying, onPlayClick: onPlayClick })))) : null));
229
+ }, elapsedTimePercent: playedPercent, type: customControlsType, isPaused: !isPlaying, onPlayClick: onPlayClick, muteButtonShown: muteButtonShown, shown: hovered && ((!started && !previewImgUrl) || started), positioning: positioning })))) : null));
225
230
  });
226
- function getHeight(width) {
227
- return (width / 16) * 9;
231
+ function getHeight(width, ratio = 9 / 16) {
232
+ return width * ratio;
228
233
  }
229
234
  function getParentElement(element) {
230
235
  const parentElement = element.parentElement;
@@ -29,6 +29,11 @@ export declare enum CustomControlsType {
29
29
  WithMuteButton = "with-mute-button",
30
30
  WithPlayPauseButton = "with-play-pause-button"
31
31
  }
32
+ export declare enum CustomControlsButtonPositioning {
33
+ Left = "left",
34
+ Right = "right",
35
+ Center = "center"
36
+ }
32
37
  export declare enum MediaVideoType {
33
38
  Default = "default",
34
39
  Player = "player"
@@ -158,6 +163,8 @@ export interface ButtonImageProps {
158
163
  }
159
164
  export interface CustomControlsOptions {
160
165
  type?: CustomControlsType;
166
+ muteButtonShown?: boolean;
167
+ positioning?: CustomControlsButtonPositioning;
161
168
  }
162
169
  export interface PlayButtonProps extends ClassNameProps {
163
170
  type?: PlayButtonType;
@@ -168,6 +175,7 @@ export type ThemedMediaVideoProps = ThemeSupporting<MediaVideoProps>;
168
175
  export interface MediaComponentVideoProps extends AnalyticsEventsBase {
169
176
  video: MediaVideoProps;
170
177
  height?: number;
178
+ ratio?: number;
171
179
  metrika?: MetrikaVideo;
172
180
  previewImg?: string;
173
181
  }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MediaVideoControlsType = exports.MediaVideoType = exports.CustomControlsType = exports.PlayButtonThemes = exports.PlayButtonType = exports.PriceLabelColor = exports.PriceDetailsType = exports.AuthorType = void 0;
3
+ exports.MediaVideoControlsType = exports.MediaVideoType = exports.CustomControlsButtonPositioning = exports.CustomControlsType = exports.PlayButtonThemes = exports.PlayButtonType = exports.PriceLabelColor = exports.PriceDetailsType = exports.AuthorType = void 0;
4
4
  // enums
5
5
  var AuthorType;
6
6
  (function (AuthorType) {
@@ -35,6 +35,12 @@ var CustomControlsType;
35
35
  CustomControlsType["WithMuteButton"] = "with-mute-button";
36
36
  CustomControlsType["WithPlayPauseButton"] = "with-play-pause-button";
37
37
  })(CustomControlsType = exports.CustomControlsType || (exports.CustomControlsType = {}));
38
+ var CustomControlsButtonPositioning;
39
+ (function (CustomControlsButtonPositioning) {
40
+ CustomControlsButtonPositioning["Left"] = "left";
41
+ CustomControlsButtonPositioning["Right"] = "right";
42
+ CustomControlsButtonPositioning["Center"] = "center";
43
+ })(CustomControlsButtonPositioning = exports.CustomControlsButtonPositioning || (exports.CustomControlsButtonPositioning = {}));
38
44
  var MediaVideoType;
39
45
  (function (MediaVideoType) {
40
46
  MediaVideoType["Default"] = "default";
@@ -8,7 +8,7 @@ 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, qa, } = 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, ratio, } = props;
12
12
  const [hasVideoFallback, setHasVideoFallback] = useState(false);
13
13
  const qaAttributes = getQaAttrubutes(qa, 'video');
14
14
  const content = useMemo(() => {
@@ -30,6 +30,7 @@ export const Media = (props) => {
30
30
  customBarControlsClassName,
31
31
  hasVideoFallback,
32
32
  setHasVideoFallback,
33
+ ratio,
33
34
  };
34
35
  if (fullscreen) {
35
36
  result.push(React.createElement(FullscreenVideo, Object.assign({}, videoProps, { qa: qaAttributes.video })));
@@ -65,6 +66,7 @@ export const Media = (props) => {
65
66
  previewImg,
66
67
  playButton,
67
68
  customBarControlsClassName,
69
+ ratio,
68
70
  youtubeClassName,
69
71
  ]);
70
72
  return (React.createElement("div", { className: b(null, className), style: { backgroundColor: color }, "data-qa": qa }, content));
@@ -6,7 +6,7 @@ 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, qa, } = props;
9
+ const { video, height, metrika, analyticsEvents, previewImg, playButton: commonPlayButton, customBarControlsClassName, videoClassName, playVideo, setHasVideoFallback, hasVideoFallback, qa, ratio, } = props;
10
10
  const qaAttributes = getQaAttrubutes(qa, 'source');
11
11
  const ref = useRef(null);
12
12
  useEffect(() => {
@@ -30,7 +30,7 @@ const Video = (props) => {
30
30
  }, [playVideo, video, setHasVideoFallback]);
31
31
  const reactPlayerBlock = useMemo(() => {
32
32
  const { src, loop, controls, muted, autoplay = true, elapsedTime, playButton, ariaLabel, customControlsOptions, } = video;
33
- 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, ariaLabel: ariaLabel, customControlsOptions: customControlsOptions }));
33
+ 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, ariaLabel: ariaLabel, customControlsOptions: customControlsOptions, ratio: ratio }));
34
34
  }, [
35
35
  video,
36
36
  height,
@@ -41,6 +41,7 @@ const Video = (props) => {
41
41
  customBarControlsClassName,
42
42
  metrika,
43
43
  analyticsEvents,
44
+ ratio,
44
45
  ]);
45
46
  const defaultVideoBlock = useMemo(() => {
46
47
  return video.src.length && !hasVideoFallback ? (React.createElement("div", { className: b('wrap', videoClassName), style: { height }, "data-qa": qaAttributes.default },
@@ -1,36 +1,43 @@
1
+ .pc-CustomBarControls__button_type_with-play-pause-button {
2
+ box-shadow: 0px 4px 24px var(--pc-color-sfx-shadow), 0px 2px 8px var(--pc-color-sfx-shadow);
3
+ }
4
+
5
+ .pc-CustomBarControls__button_type_with-play-pause-button:hover {
6
+ box-shadow: 0px 4px 24px var(--g-color-sfx-shadow), 0px 2px 8px var(--g-color-sfx-shadow);
7
+ cursor: pointer;
8
+ }
9
+
1
10
  /* use this for style redefinitions to awoid problems with
2
11
  unpredictable css rules order in build */
3
12
  .pc-CustomBarControls__wrapper {
4
13
  position: absolute;
5
14
  bottom: 0;
15
+ opacity: 0;
16
+ transition: opacity 300ms ease 3s;
17
+ }
18
+ .pc-CustomBarControls__wrapper_shown {
19
+ opacity: 1;
20
+ transition: opacity 0s ease 0s;
6
21
  }
7
22
  .pc-CustomBarControls__wrapper_type_with-play-pause-button {
8
- width: 100%;
9
- padding: 20px;
23
+ gap: 8px;
24
+ padding: 8px;
25
+ }
26
+ .pc-CustomBarControls__wrapper_positioning_left, .pc-CustomBarControls__wrapper_positioning_right, .pc-CustomBarControls__wrapper_positioning_center {
10
27
  display: flex;
11
- gap: 20px;
28
+ width: 100%;
29
+ }
30
+ .pc-CustomBarControls__wrapper_positioning_right {
31
+ flex-direction: row-reverse;
32
+ }
33
+ .pc-CustomBarControls__wrapper_positioning_center {
34
+ justify-content: center;
12
35
  }
13
36
  .pc-CustomBarControls__button {
14
37
  border: 0;
15
38
  padding: 0;
16
39
  cursor: pointer;
17
40
  }
18
- .pc-CustomBarControls__button_type_with-play-pause-button {
19
- opacity: 0.9;
20
- background-color: transparent;
21
- transition: opacity 300ms ease 3s;
22
- }
23
- .pc-CustomBarControls__button_type_with-play-pause-button:hover, .pc-CustomBarControls__button_type_with-play-pause-button:focus {
24
- opacity: 1;
25
- }
26
- .pc-CustomBarControls__button_type_with-play-pause-button:focus {
27
- outline: 1px solid var(--g-color-line-light);
28
- outline-offset: 2px;
29
- border-radius: 4px;
30
- }
31
- .pc-CustomBarControls__button_type_with-play-pause-button:focus:not(:focus-visible) {
32
- outline: none;
33
- }
34
41
  .pc-CustomBarControls__button_type_with-mute-button {
35
42
  border-radius: 50%;
36
43
  display: flex;
@@ -53,15 +60,29 @@ unpredictable css rules order in build */
53
60
  .pc-CustomBarControls__button_type_with-mute-button:focus:not(:focus-visible) {
54
61
  outline: none;
55
62
  }
56
- .pc-CustomBarControls__play-icon {
57
- height: 24px;
58
- width: 24px;
63
+ .pc-CustomBarControls__button_type_with-play-pause-button {
64
+ width: 42px;
65
+ height: 42px;
66
+ border-radius: 50%;
67
+ background: var(--g-color-base-background);
68
+ }
69
+ .pc-CustomBarControls__button_type_with-play-pause-button:focus {
70
+ outline: 2px solid var(--g-color-line-misc);
71
+ }
72
+ .pc-CustomBarControls__button_type_with-play-pause-button:focus:not(:focus-visible) {
73
+ outline: none;
74
+ }
75
+ .pc-CustomBarControls__play-icon_type_with-play-pause-button {
76
+ height: 16px;
77
+ width: 16px;
78
+ color: var(--g-color-base-neutral-heavy);
59
79
  }
60
80
  .pc-CustomBarControls__mute-icon_type_with-mute-button {
61
81
  height: 22px;
62
82
  width: 32px;
63
83
  }
64
84
  .pc-CustomBarControls__mute-icon_type_with-play-pause-button {
65
- height: 24px;
66
- width: 24px;
85
+ height: 16px;
86
+ width: 16px;
87
+ color: var(--g-color-base-neutral-heavy);
67
88
  }
@@ -1,16 +1,17 @@
1
1
  import React from 'react';
2
- import { ClassNameProps, CustomControlsType } from '../../models';
2
+ import { ClassNameProps, CustomControlsOptions, CustomControlsType } from '../../models';
3
3
  import './CustomBarControls.css';
4
4
  interface MuteConfigProps {
5
5
  isMuted: boolean;
6
6
  changeMute: (event: React.MouseEvent) => void;
7
7
  }
8
- export interface CustomBarControlsProps extends ClassNameProps {
8
+ export interface CustomBarControlsProps extends ClassNameProps, CustomControlsOptions {
9
9
  mute?: MuteConfigProps;
10
10
  elapsedTimePercent?: number;
11
11
  type?: CustomControlsType;
12
12
  isPaused?: boolean;
13
13
  onPlayClick?: () => void;
14
+ shown?: boolean;
14
15
  }
15
16
  declare const CustomBarControls: (props: CustomBarControlsProps) => JSX.Element;
16
17
  export default CustomBarControls;