@gravity-ui/page-constructor 1.14.1 → 1.14.3

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 (75) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/build/cjs/components/FullscreenImage/FullscreenImage.js +8 -6
  3. package/build/cjs/components/FullscreenMedia/FullScreenMedia.css +70 -0
  4. package/build/cjs/components/FullscreenMedia/FullScreenMedia.d.ts +9 -0
  5. package/build/cjs/components/FullscreenMedia/FullScreenMedia.js +40 -0
  6. package/build/cjs/components/Media/Media.js +3 -2
  7. package/build/cjs/components/MetaInfo/MetaInfo.css +13 -0
  8. package/build/cjs/components/MetaInfo/MetaInfo.d.ts +6 -0
  9. package/build/cjs/components/MetaInfo/MetaInfo.js +8 -0
  10. package/build/cjs/components/MetaInfo/schema.d.ts +8 -0
  11. package/build/cjs/components/MetaInfo/schema.js +10 -0
  12. package/build/cjs/components/VideoBlock/VideoBlock.d.ts +1 -0
  13. package/build/cjs/components/VideoBlock/VideoBlock.js +6 -10
  14. package/build/cjs/components/index.d.ts +2 -0
  15. package/build/cjs/components/index.js +5 -1
  16. package/build/cjs/constructor-items.d.ts +4 -0
  17. package/build/cjs/constructor-items.js +4 -0
  18. package/build/cjs/containers/PageConstructor/PageConstructor.css +1 -0
  19. package/build/cjs/models/constructor-items/common.d.ts +1 -17
  20. package/build/cjs/models/constructor-items/sub-blocks.d.ts +14 -0
  21. package/build/cjs/models/constructor-items/sub-blocks.js +4 -0
  22. package/build/cjs/schema/index.js +1 -0
  23. package/build/cjs/schema/validators/sub-blocks.d.ts +1 -0
  24. package/build/cjs/schema/validators/sub-blocks.js +1 -0
  25. package/build/cjs/sub-blocks/HubspotForm/HubspotForm.css +2 -2
  26. package/build/cjs/sub-blocks/LayoutItem/LayoutItem.css +16 -0
  27. package/build/cjs/sub-blocks/LayoutItem/LayoutItem.d.ts +3 -0
  28. package/build/cjs/sub-blocks/LayoutItem/LayoutItem.js +21 -0
  29. package/build/cjs/sub-blocks/LayoutItem/schema.d.ts +218 -0
  30. package/build/cjs/sub-blocks/LayoutItem/schema.js +18 -0
  31. package/build/cjs/sub-blocks/LayoutItem/utils.d.ts +15 -0
  32. package/build/cjs/sub-blocks/LayoutItem/utils.js +12 -0
  33. package/build/cjs/sub-blocks/index.d.ts +1 -0
  34. package/build/cjs/sub-blocks/index.js +3 -1
  35. package/build/cjs/text-transform/blocks.js +17 -0
  36. package/build/esm/components/FullscreenImage/FullscreenImage.js +9 -7
  37. package/build/esm/components/FullscreenMedia/FullScreenMedia.css +70 -0
  38. package/build/esm/components/FullscreenMedia/FullScreenMedia.d.ts +10 -0
  39. package/build/esm/components/FullscreenMedia/FullScreenMedia.js +38 -0
  40. package/build/esm/components/Media/Media.js +3 -2
  41. package/build/esm/components/MetaInfo/MetaInfo.css +13 -0
  42. package/build/esm/components/MetaInfo/MetaInfo.d.ts +7 -0
  43. package/build/esm/components/MetaInfo/MetaInfo.js +6 -0
  44. package/build/esm/components/MetaInfo/schema.d.ts +8 -0
  45. package/build/esm/components/MetaInfo/schema.js +8 -0
  46. package/build/esm/components/VideoBlock/VideoBlock.d.ts +1 -0
  47. package/build/esm/components/VideoBlock/VideoBlock.js +6 -10
  48. package/build/esm/components/index.d.ts +2 -0
  49. package/build/esm/components/index.js +2 -0
  50. package/build/esm/constructor-items.d.ts +4 -0
  51. package/build/esm/constructor-items.js +5 -1
  52. package/build/esm/containers/PageConstructor/PageConstructor.css +1 -0
  53. package/build/esm/models/constructor-items/common.d.ts +1 -17
  54. package/build/esm/models/constructor-items/sub-blocks.d.ts +14 -0
  55. package/build/esm/models/constructor-items/sub-blocks.js +4 -0
  56. package/build/esm/schema/index.js +1 -0
  57. package/build/esm/schema/validators/sub-blocks.d.ts +1 -0
  58. package/build/esm/schema/validators/sub-blocks.js +1 -0
  59. package/build/esm/sub-blocks/HubspotForm/HubspotForm.css +2 -2
  60. package/build/esm/sub-blocks/LayoutItem/LayoutItem.css +16 -0
  61. package/build/esm/sub-blocks/LayoutItem/LayoutItem.d.ts +4 -0
  62. package/build/esm/sub-blocks/LayoutItem/LayoutItem.js +20 -0
  63. package/build/esm/sub-blocks/LayoutItem/schema.d.ts +218 -0
  64. package/build/esm/sub-blocks/LayoutItem/schema.js +14 -0
  65. package/build/esm/sub-blocks/LayoutItem/utils.d.ts +15 -0
  66. package/build/esm/sub-blocks/LayoutItem/utils.js +6 -0
  67. package/build/esm/sub-blocks/index.d.ts +1 -0
  68. package/build/esm/sub-blocks/index.js +1 -0
  69. package/build/esm/text-transform/blocks.js +17 -0
  70. package/package.json +4 -2
  71. package/server/models/constructor-items/common.d.ts +1 -17
  72. package/server/models/constructor-items/sub-blocks.d.ts +14 -0
  73. package/server/models/constructor-items/sub-blocks.js +4 -0
  74. package/server/text-transform/blocks.js +17 -0
  75. package/styles/root.scss +1 -0
@@ -0,0 +1,218 @@
1
+ export declare const LayoutItem: {
2
+ type: string;
3
+ additionalProperties: boolean;
4
+ required: string[];
5
+ properties: {
6
+ media: {
7
+ color: {
8
+ type: string;
9
+ };
10
+ image: {
11
+ anyOf: ({
12
+ oneOf: ({
13
+ type: string;
14
+ properties: {
15
+ when: {
16
+ type: string;
17
+ };
18
+ };
19
+ } | {
20
+ type: string;
21
+ pattern: string;
22
+ })[];
23
+ } | {
24
+ type: string;
25
+ items: {
26
+ oneOf: ({
27
+ type: string;
28
+ properties: {
29
+ when: {
30
+ type: string;
31
+ };
32
+ };
33
+ } | {
34
+ type: string;
35
+ pattern: string;
36
+ })[];
37
+ };
38
+ })[];
39
+ };
40
+ video: {
41
+ type: string;
42
+ additionalProperties: boolean;
43
+ required: string[];
44
+ properties: {
45
+ src: {
46
+ type: string;
47
+ items: {
48
+ type: string;
49
+ };
50
+ };
51
+ loop: {
52
+ anyOf: ({
53
+ type: string;
54
+ additionalProperties: boolean;
55
+ required: string[];
56
+ properties: {
57
+ start: {
58
+ type: string;
59
+ };
60
+ end: {
61
+ type: string;
62
+ };
63
+ };
64
+ } | {
65
+ type: string;
66
+ })[];
67
+ };
68
+ type: {
69
+ type: string;
70
+ enum: string[];
71
+ };
72
+ muted: {
73
+ type: string;
74
+ };
75
+ playing: {
76
+ type: string;
77
+ };
78
+ elapsedTime: {
79
+ type: string;
80
+ };
81
+ playIcon: {
82
+ type: string;
83
+ additionalProperties: boolean;
84
+ properties: {
85
+ type: {
86
+ type: string;
87
+ enum: string[];
88
+ };
89
+ theme: {
90
+ type: string;
91
+ enum: string[];
92
+ };
93
+ text: {
94
+ type: string;
95
+ contentType: string;
96
+ };
97
+ };
98
+ };
99
+ controls: {
100
+ type: string;
101
+ enum: string[];
102
+ };
103
+ };
104
+ };
105
+ youtube: {
106
+ type: string;
107
+ };
108
+ parallax: {
109
+ type: string;
110
+ };
111
+ height: {
112
+ type: string;
113
+ };
114
+ previewImg: {
115
+ type: string;
116
+ };
117
+ dataLens: {
118
+ oneOf: ({
119
+ type: string;
120
+ additionalProperties: boolean;
121
+ required: string[];
122
+ properties: {
123
+ id: {
124
+ type: string;
125
+ };
126
+ theme: {
127
+ type: string;
128
+ enum: string[];
129
+ };
130
+ };
131
+ } | {
132
+ type: string;
133
+ })[];
134
+ };
135
+ };
136
+ content: Partial<{
137
+ title: {
138
+ oneOf: ({
139
+ type: string;
140
+ additionalProperties: boolean;
141
+ required: string[];
142
+ properties: {
143
+ text: {
144
+ type: string;
145
+ contentType: string;
146
+ };
147
+ textSize: {
148
+ type: string;
149
+ enum: string[];
150
+ };
151
+ url: {
152
+ type: string;
153
+ };
154
+ resetMargin: {
155
+ type: string;
156
+ };
157
+ };
158
+ } | {
159
+ type: string;
160
+ contentType: string;
161
+ })[];
162
+ };
163
+ text: {
164
+ type: string;
165
+ contentType: string;
166
+ };
167
+ additionalInfo: {
168
+ type: string;
169
+ contentType: string;
170
+ };
171
+ size: {
172
+ type: string;
173
+ enum: string[];
174
+ };
175
+ links: {
176
+ type: string;
177
+ items: {
178
+ type: string;
179
+ properties: {
180
+ when: {
181
+ type: string;
182
+ };
183
+ };
184
+ };
185
+ };
186
+ buttons: {
187
+ type: string;
188
+ items: {
189
+ type: string;
190
+ properties: {
191
+ when: {
192
+ type: string;
193
+ };
194
+ };
195
+ };
196
+ };
197
+ theme: {
198
+ type: string;
199
+ enum: string[];
200
+ };
201
+ }>;
202
+ metaInfo: {
203
+ type: string;
204
+ items: {
205
+ type: string;
206
+ contentType: string;
207
+ };
208
+ };
209
+ border: {
210
+ type: string;
211
+ };
212
+ fullScreen: {
213
+ type: string;
214
+ };
215
+ type: {};
216
+ when: {};
217
+ };
218
+ };
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LayoutItem = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const lodash_1 = require("lodash");
6
+ const common_1 = require("../../schema/validators/common");
7
+ const schema_1 = require("../../sub-blocks/Content/schema");
8
+ const schema_2 = tslib_1.__importDefault(require("../../components/MetaInfo/schema"));
9
+ exports.LayoutItem = {
10
+ type: 'object',
11
+ additionalProperties: false,
12
+ required: ['content', 'media'],
13
+ properties: Object.assign(Object.assign({}, common_1.BaseProps), { media: common_1.MediaProps, content: (0, lodash_1.omit)(schema_1.ContentBase, ['colSize', 'size', 'centered']), metaInfo: schema_2.default, border: {
14
+ type: 'boolean',
15
+ }, fullScreen: {
16
+ type: 'boolean',
17
+ } }),
18
+ };
@@ -0,0 +1,15 @@
1
+ import { LayoutItemProps, LinkTheme, MediaProps } from '../../models';
2
+ export declare const getLayoutItemLinks: (links: LayoutItemProps['content']['links']) => {
3
+ url: string;
4
+ text?: string | undefined;
5
+ textSize?: import("../../models").TextSize | undefined;
6
+ theme: LinkTheme;
7
+ colorTheme?: import("../../models").TextTheme | undefined;
8
+ arrow?: boolean | undefined;
9
+ target?: string | undefined;
10
+ metrikaGoals?: import("../../models").MetrikaGoal | undefined;
11
+ pixelEvents?: import("../../models").ButtonPixel | undefined;
12
+ className?: string | undefined;
13
+ }[] | undefined;
14
+ export declare const hasFullScreen: ({ dataLens, image }: MediaProps) => boolean;
15
+ export declare const showFullScreenIcon: ({ youtube }: MediaProps) => boolean;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.showFullScreenIcon = exports.hasFullScreen = exports.getLayoutItemLinks = void 0;
4
+ const getLayoutItemLinks = (links) => links === null || links === void 0 ? void 0 : links.map((link) => (Object.assign({ theme: 'normal' }, link)));
5
+ exports.getLayoutItemLinks = getLayoutItemLinks;
6
+ const hasFullScreen = ({ dataLens, image }) => {
7
+ // datalens and slider media card don't support fullScreen mode
8
+ return !(dataLens || Array.isArray(image));
9
+ };
10
+ exports.hasFullScreen = hasFullScreen;
11
+ const showFullScreenIcon = ({ youtube }) => !youtube;
12
+ exports.showFullScreenIcon = showFullScreenIcon;
@@ -7,6 +7,7 @@ export { default as MediaCard } from './MediaCard/MediaCard';
7
7
  export { default as BannerCard } from './BannerCard/BannerCard';
8
8
  export { default as TutorialCard } from './TutorialCard/TutorialCard';
9
9
  export { default as CardWithImage } from './CardWithImage/CardWithImage';
10
+ export { default as LayoutItem } from './LayoutItem/LayoutItem';
10
11
  export { default as BackgroundCard } from './BackgroundCard/BackgroundCard';
11
12
  export { default as BasicCard } from './BasicCard/BasicCard';
12
13
  export { default as Content } from './Content/Content';
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.HubspotForm = exports.Content = exports.BasicCard = exports.BackgroundCard = exports.CardWithImage = exports.TutorialCard = exports.BannerCard = exports.MediaCard = exports.PriceDetailed = exports.Partner = exports.NewsCard = exports.Quote = exports.Divider = void 0;
6
+ exports.HubspotForm = exports.Content = exports.BasicCard = exports.BackgroundCard = exports.LayoutItem = exports.CardWithImage = exports.TutorialCard = exports.BannerCard = exports.MediaCard = exports.PriceDetailed = exports.Partner = exports.NewsCard = exports.Quote = exports.Divider = void 0;
7
7
  var Divider_1 = require("./Divider/Divider");
8
8
  Object.defineProperty(exports, "Divider", { enumerable: true, get: function () { return __importDefault(Divider_1).default; } });
9
9
  var Quote_1 = require("./Quote/Quote");
@@ -22,6 +22,8 @@ var TutorialCard_1 = require("./TutorialCard/TutorialCard");
22
22
  Object.defineProperty(exports, "TutorialCard", { enumerable: true, get: function () { return __importDefault(TutorialCard_1).default; } });
23
23
  var CardWithImage_1 = require("./CardWithImage/CardWithImage");
24
24
  Object.defineProperty(exports, "CardWithImage", { enumerable: true, get: function () { return __importDefault(CardWithImage_1).default; } });
25
+ var LayoutItem_1 = require("./LayoutItem/LayoutItem");
26
+ Object.defineProperty(exports, "LayoutItem", { enumerable: true, get: function () { return __importDefault(LayoutItem_1).default; } });
25
27
  var BackgroundCard_1 = require("./BackgroundCard/BackgroundCard");
26
28
  Object.defineProperty(exports, "BackgroundCard", { enumerable: true, get: function () { return __importDefault(BackgroundCard_1).default; } });
27
29
  var BasicCard_1 = require("./BasicCard/BasicCard");
@@ -144,6 +144,23 @@ const config = {
144
144
  transformer: typografTransformer,
145
145
  },
146
146
  ],
147
+ [models_1.SubBlockType.LayoutItem]: [
148
+ {
149
+ fields: ['content'],
150
+ parser: parseContentLayout,
151
+ transformer: yfmTransformer,
152
+ },
153
+ {
154
+ fields: ['content'],
155
+ parser: parseContentLayoutTitle,
156
+ transformer: typografTransformer,
157
+ },
158
+ {
159
+ fields: ['metaInfo'],
160
+ parser: (0, exports.createItemsParser)([]),
161
+ transformer: typografTransformer,
162
+ },
163
+ ],
147
164
  [models_1.SubBlockType.Quote]: {
148
165
  fields: ['text'],
149
166
  transformer: typografTransformer,
@@ -1,27 +1,29 @@
1
- import React, { useState, useCallback } from 'react';
1
+ import React, { useState } from 'react';
2
2
  import { Icon, Modal } from '@gravity-ui/uikit';
3
3
  import { block } from '../../utils';
4
4
  import Image from '../Image/Image';
5
5
  import { PreviewClose, FullScreen } from '../../icons';
6
6
  import './FullScreenImage.css';
7
7
  const b = block('FullScreenImage');
8
+ const FULL_SCREEN_ICON_SIZE = 18;
9
+ const CLOSE_ICON_SIZE = 30;
8
10
  const FullScreenImage = (props) => {
9
11
  const { imageClassName, modalImageClass, imageStyle } = props;
10
12
  const [isOpened, setIsOpened] = useState(false);
11
13
  const [isMouseEnter, setIsMouseEnter] = useState(false);
12
- const openModal = useCallback(() => setIsOpened(true), []);
13
- const closeModal = useCallback(() => setIsOpened(false), []);
14
- const showFullScreenIcon = useCallback(() => setIsMouseEnter(true), []);
15
- const hideFullScreenIcon = useCallback(() => setIsMouseEnter(false), []);
14
+ const openModal = () => setIsOpened(true);
15
+ const closeModal = () => setIsOpened(false);
16
+ const showFullScreenIcon = () => setIsMouseEnter(true);
17
+ const hideFullScreenIcon = () => setIsMouseEnter(false);
16
18
  return (React.createElement("div", { className: b() },
17
19
  React.createElement("div", { className: b('image-wrapper'), onMouseEnter: showFullScreenIcon, onMouseLeave: hideFullScreenIcon },
18
20
  React.createElement(Image, Object.assign({}, props, { className: b('image', imageClassName), onClick: openModal, style: imageStyle })),
19
21
  React.createElement("div", { className: b('icon-wrapper', { visible: isMouseEnter }), onClick: openModal },
20
- React.createElement(Icon, { data: FullScreen, width: 18, height: 18, className: b('icon') }))),
22
+ React.createElement(Icon, { data: FullScreen, width: FULL_SCREEN_ICON_SIZE, height: FULL_SCREEN_ICON_SIZE, className: b('icon') }))),
21
23
  isOpened && (React.createElement(Modal, { open: isOpened, onClose: closeModal, className: b('modal') },
22
24
  React.createElement("div", { className: b('modal-content') },
23
25
  React.createElement("div", { className: b('icon-wrapper', { visible: true }), onClick: closeModal },
24
- React.createElement(Icon, { data: PreviewClose, width: 30, height: 30, className: b('icon', { hover: true }) })),
26
+ React.createElement(Icon, { data: PreviewClose, width: CLOSE_ICON_SIZE, height: CLOSE_ICON_SIZE, className: b('icon', { hover: true }) })),
25
27
  React.createElement(Image, Object.assign({}, props, { className: b('modal-image', modalImageClass) })))))));
26
28
  };
27
29
  export default FullScreenImage;
@@ -0,0 +1,70 @@
1
+ /* use this for style redefinitions to awoid problems with
2
+ unpredictable css rules order in build */
3
+ .pc-full-screen-media__modal-media_type_youtube, .pc-full-screen-media__modal-media_type_video video, .pc-full-screen-media__modal-media_type_image {
4
+ display: block;
5
+ position: relative;
6
+ width: 100%;
7
+ max-width: 1232px;
8
+ max-height: 70vh;
9
+ }
10
+
11
+ .pc-full-screen-media__media {
12
+ cursor: pointer;
13
+ }
14
+ .pc-full-screen-media__media-wrapper {
15
+ cursor: pointer;
16
+ position: relative;
17
+ }
18
+ .pc-full-screen-media__modal-content {
19
+ position: relative;
20
+ }
21
+ .pc-full-screen-media__inline-media {
22
+ transform: translateZ(0);
23
+ }
24
+ .pc-full-screen-media__modal-media {
25
+ border-radius: var(--pc-border-radius);
26
+ }
27
+ .pc-full-screen-media__modal-media_type_youtube {
28
+ width: 70vw;
29
+ height: calc(70vw * 9 / 16);
30
+ }
31
+ .pc-full-screen-media__modal .yc-modal__content, .pc-full-screen-media__modal-image {
32
+ border-radius: var(--pc-border-radius);
33
+ }
34
+ .pc-full-screen-media__icon-wrapper {
35
+ display: flex;
36
+ align-items: center;
37
+ justify-content: center;
38
+ position: absolute;
39
+ right: 16px;
40
+ top: 16px;
41
+ width: 36px;
42
+ height: 36px;
43
+ border-radius: 8px;
44
+ background-color: var(--yc-color-base-simple-hover-solid);
45
+ cursor: pointer;
46
+ z-index: 10;
47
+ }
48
+ .pc-full-screen-media__modal-content .pc-full-screen-media__icon-wrapper, .pc-full-screen-media__media-wrapper .pc-full-screen-media__icon-wrapper {
49
+ opacity: 0;
50
+ transition: opacity 0.3s;
51
+ pointer-events: none;
52
+ }
53
+ .pc-full-screen-media__modal-content:hover .pc-full-screen-media__icon-wrapper, .pc-full-screen-media__media-wrapper:hover .pc-full-screen-media__icon-wrapper {
54
+ opacity: 1;
55
+ pointer-events: inherit;
56
+ }
57
+ .pc-full-screen-media__icon {
58
+ color: var(--yc-color-text-hint);
59
+ }
60
+ .pc-full-screen-media__icon_hover:hover {
61
+ color: var(--yc-color-text-secondary);
62
+ }
63
+ @media (max-width: 577px) {
64
+ .pc-full-screen-media__icon-wrapper {
65
+ display: none;
66
+ }
67
+ .pc-full-screen-media__modal {
68
+ display: none !important; /* stylelint-disable-line declaration-no-important */
69
+ }
70
+ }
@@ -0,0 +1,10 @@
1
+ /// <reference types="react" />
2
+ import { MediaAllProps } from '../Media/Media';
3
+ import './FullScreenMedia.css';
4
+ export type ChildMediaRenderProps = Pick<MediaAllProps, 'fullScreen' | 'imageClassName' | 'videoClassName' | 'youtubeClassName' | 'className'>;
5
+ export interface FullScreenMediaProps {
6
+ showFullScreenIcon?: boolean;
7
+ children: (props?: ChildMediaRenderProps) => JSX.Element;
8
+ }
9
+ declare const FullScreenMedia: ({ children, showFullScreenIcon }: FullScreenMediaProps) => JSX.Element;
10
+ export default FullScreenMedia;
@@ -0,0 +1,38 @@
1
+ import React, { useContext, useState } from 'react';
2
+ import { Icon, Modal } from '@gravity-ui/uikit';
3
+ import { block } from '../../utils';
4
+ import { PreviewClose, FullScreen } from '../../icons';
5
+ import { MobileContext } from '../../context/mobileContext';
6
+ import './FullScreenMedia.css';
7
+ const b = block('full-screen-media');
8
+ const FULL_SCREEN_ICON_SIZE = 18;
9
+ const CLOSE_ICON_SIZE = 30;
10
+ const getMediaClass = (type) => b('modal-media', { type });
11
+ const FullScreenMedia = ({ children, showFullScreenIcon = true }) => {
12
+ const [isOpened, setIsOpened] = useState(false);
13
+ const isMobile = useContext(MobileContext);
14
+ const openModal = (e) => {
15
+ e.stopPropagation();
16
+ setIsOpened(true);
17
+ };
18
+ const closeModal = () => setIsOpened(false);
19
+ if (isMobile) {
20
+ return children();
21
+ }
22
+ return (React.createElement("div", { className: b() },
23
+ React.createElement("div", { className: b('media-wrapper'), onClickCapture: openModal },
24
+ children({ className: b('inline-media') }),
25
+ showFullScreenIcon && (React.createElement("div", { className: b('icon-wrapper'), onClickCapture: openModal },
26
+ React.createElement(Icon, { data: FullScreen, width: FULL_SCREEN_ICON_SIZE, height: FULL_SCREEN_ICON_SIZE, className: b('icon') })))),
27
+ isOpened && (React.createElement(Modal, { open: isOpened, onClose: closeModal, className: b('modal') },
28
+ React.createElement("div", { className: b('modal-content') },
29
+ React.createElement("div", { className: b('icon-wrapper', { visible: true }), onClick: closeModal },
30
+ React.createElement(Icon, { data: PreviewClose, width: CLOSE_ICON_SIZE, height: CLOSE_ICON_SIZE, className: b('icon', { hover: true }) })),
31
+ children({
32
+ imageClassName: getMediaClass('image'),
33
+ videoClassName: getMediaClass('video'),
34
+ youtubeClassName: getMediaClass('youtube'),
35
+ fullScreen: true,
36
+ }))))));
37
+ };
38
+ export default FullScreenMedia;
@@ -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, fullScreen, } = 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(() => {
@@ -19,7 +19,7 @@ export const Media = (props) => {
19
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 }));
20
20
  }
21
21
  if (youtube) {
22
- result = (React.createElement(YoutubeBlock, { className: b('youtube', youtubeClassName), record: youtube, attributes: { color: 'white', rel: '0' }, previewImg: previewImg, height: height }));
22
+ result = (React.createElement(YoutubeBlock, { className: b('youtube', youtubeClassName), record: youtube, attributes: { color: 'white', rel: '0' }, previewImg: previewImg, height: height, fullScreen: fullScreen }));
23
23
  }
24
24
  if (dataLens) {
25
25
  result = React.createElement(DataLens, { dataLens: dataLens });
@@ -42,6 +42,7 @@ export const Media = (props) => {
42
42
  playButton,
43
43
  customBarControlsClassName,
44
44
  youtubeClassName,
45
+ fullScreen,
45
46
  ]);
46
47
  return (React.createElement("div", { className: b(null, className), style: { backgroundColor: color } }, content));
47
48
  };
@@ -0,0 +1,13 @@
1
+ /* use this for style redefinitions to awoid problems with
2
+ unpredictable css rules order in build */
3
+ .pc-meta-info {
4
+ font-size: var(--yc-text-body-2-font-size);
5
+ line-height: var(--yc-text-body-2-line-height);
6
+ display: flex;
7
+ align-items: center;
8
+ font-weight: 500;
9
+ color: var(--pc-media-card-meta-info-color);
10
+ }
11
+ .pc-meta-info__item:not(:first-child) {
12
+ margin-left: 16px;
13
+ }
@@ -0,0 +1,7 @@
1
+ import { ClassNameProps } from 'src/models';
2
+ import './MetaInfo.css';
3
+ export interface MetaInfpoProps extends ClassNameProps {
4
+ items: string[];
5
+ }
6
+ declare const MetaInfo: ({ items, className }: MetaInfpoProps) => JSX.Element;
7
+ export default MetaInfo;
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { block } from '../../utils';
3
+ import './MetaInfo.css';
4
+ const b = block('meta-info');
5
+ const MetaInfo = ({ items, className }) => (React.createElement("div", { className: b(null, className) }, items.map((metaInfoItem) => (React.createElement("div", { key: metaInfoItem, className: b('item') }, metaInfoItem)))));
6
+ export default MetaInfo;
@@ -0,0 +1,8 @@
1
+ declare const metaInfo: {
2
+ type: string;
3
+ items: {
4
+ type: string;
5
+ contentType: string;
6
+ };
7
+ };
8
+ export default metaInfo;
@@ -0,0 +1,8 @@
1
+ const metaInfo = {
2
+ type: 'array',
3
+ items: {
4
+ type: 'string',
5
+ contentType: 'text',
6
+ },
7
+ };
8
+ export default metaInfo;
@@ -14,6 +14,7 @@ export interface VideoBlockProps {
14
14
  previewImg?: string;
15
15
  playButton?: React.ReactNode;
16
16
  height?: number;
17
+ fullScreen?: boolean;
17
18
  }
18
19
  declare const VideoBlock: (props: VideoBlockProps) => JSX.Element | null;
19
20
  export default VideoBlock;
@@ -1,5 +1,6 @@
1
1
  import React, { useRef, useState, useCallback, useEffect } from 'react';
2
2
  import _ from 'lodash';
3
+ import { v4 as uuidv4 } from 'uuid';
3
4
  import { Icon } from '@gravity-ui/uikit';
4
5
  import { block, getPageSearchParams } from '../../utils';
5
6
  import Image from '../Image/Image';
@@ -15,7 +16,6 @@ export const AUTOPLAY_ATTRIBUTES = {
15
16
  mute: 1,
16
17
  };
17
18
  const b = block('VideoBlock');
18
- const iframeId = 'video-block';
19
19
  function getVideoSrc(stream, record) {
20
20
  if (!stream && !record) {
21
21
  return null;
@@ -34,14 +34,14 @@ export function getHeight(width) {
34
34
  return (width / 16) * 9;
35
35
  }
36
36
  const VideoBlock = (props) => {
37
- const { stream, record, attributes, className, id, previewImg, playButton, height } = props;
37
+ const { stream, record, attributes, className, id, previewImg, playButton, height, fullScreen } = props;
38
38
  const src = getVideoSrc(stream, record);
39
39
  const ref = useRef(null);
40
40
  const iframeRef = useRef();
41
41
  const [hidePreview, setHidePreview] = useState(false);
42
42
  const norender = (!stream && !record) || !src;
43
43
  const [currentHeight, setCurrentHeight] = useState(height || undefined);
44
- const fullId = `${iframeId}-${id || src}`;
44
+ const fullId = id || uuidv4();
45
45
  const onPreviewClick = useCallback(() => {
46
46
  if (iframeRef.current) {
47
47
  iframeRef.current.src = `${src}?${getPageSearchParams(Object.assign(Object.assign({}, AUTOPLAY_ATTRIBUTES), (attributes || {})))}`;
@@ -62,12 +62,8 @@ const VideoBlock = (props) => {
62
62
  if (norender) {
63
63
  return;
64
64
  }
65
- const prevPageVideo = document.getElementById(fullId);
66
65
  const fullSrc = `${src}?${getPageSearchParams(attributes || {})}`;
67
- if (prevPageVideo) {
68
- prevPageVideo.src = fullSrc;
69
- }
70
- else if (ref.current) {
66
+ if (ref.current && !iframeRef.current) {
71
67
  const iframe = document.createElement('iframe');
72
68
  iframe.id = fullId;
73
69
  iframe.src = fullSrc;
@@ -79,14 +75,14 @@ const VideoBlock = (props) => {
79
75
  ref.current.appendChild(iframe);
80
76
  iframeRef.current = iframe;
81
77
  }
82
- }, [stream, record, norender, src, fullId, attributes, iframeRef]);
78
+ }, [stream, record, norender, src, fullId, attributes, iframeRef, fullScreen]);
83
79
  useEffect(() => {
84
80
  setHidePreview(false);
85
81
  }, [src, setHidePreview]);
86
82
  if (norender) {
87
83
  return null;
88
84
  }
89
- return (React.createElement("div", { className: b(null, className), ref: ref, style: { height: currentHeight } }, previewImg && !hidePreview && (React.createElement("div", { className: b('preview'), onClick: onPreviewClick },
85
+ return (React.createElement("div", { className: b(null, className), ref: ref, style: { height: currentHeight } }, previewImg && !hidePreview && !fullScreen && (React.createElement("div", { className: b('preview'), onClick: onPreviewClick },
90
86
  React.createElement(Image, { src: previewImg, className: b('image'), containerClassName: b('image-wrapper') }),
91
87
  playButton || (React.createElement("button", { className: b('button') },
92
88
  React.createElement(Icon, { className: b('icon'), data: PlayVideo, size: 24 })))))));
@@ -33,4 +33,6 @@ export { default as OverflowScroller } from './OverflowScroller/OverflowScroller
33
33
  export { default as Author } from './Author/Author';
34
34
  export { default as RouterLink } from './RouterLink/RouterLink';
35
35
  export { default as HTML } from './HTML/HTML';
36
+ export { default as MetaInfo } from './MetaInfo/MetaInfo';
37
+ export { default as FullScreenMedia } from './FullscreenMedia/FullScreenMedia';
36
38
  export type { RouterLinkProps } from './RouterLink/RouterLink';
@@ -33,3 +33,5 @@ export { default as OverflowScroller } from './OverflowScroller/OverflowScroller
33
33
  export { default as Author } from './Author/Author';
34
34
  export { default as RouterLink } from './RouterLink/RouterLink';
35
35
  export { default as HTML } from './HTML/HTML';
36
+ export { default as MetaInfo } from './MetaInfo/MetaInfo';
37
+ export { default as FullScreenMedia } from './FullscreenMedia/FullScreenMedia';
@@ -34,6 +34,10 @@ export declare const subBlockMap: {
34
34
  "media-card": ({ border, ...mediaProps }: import("./models").MediaCardProps) => JSX.Element;
35
35
  "banner-card": (props: import("./models").BannerCardProps) => JSX.Element;
36
36
  "news-card": (props: import("./models").NewsCardProps) => JSX.Element;
37
+ "layout-item": ({ content: { links, ...content }, metaInfo, media, border, fullScreen, className, }: import("./models").LayoutItemProps) => JSX.Element;
38
+ /**
39
+ * @deprecated Use LayoutItem
40
+ */
37
41
  "card-with-image": ({ title, description, image, disableCompress, links, border, fullScreen, className, additionalInfo, buttons, }: import("./models").CardWithImageProps) => JSX.Element;
38
42
  "background-card": (props: import("./models").BackgroundCardProps) => JSX.Element;
39
43
  "basic-card": (props: import("./models").BasicCardProps) => JSX.Element;