@gravity-ui/page-constructor 4.28.0 → 4.29.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.
- package/build/cjs/blocks/Header/Header.css +3 -0
- package/build/cjs/blocks/Share/Share.js +5 -1
- package/build/cjs/blocks/Share/i18n/en.json +11 -1
- package/build/cjs/blocks/Share/i18n/ru.json +11 -1
- package/build/cjs/components/Author/Author.js +7 -1
- package/build/cjs/components/Author/schema.d.ts +12 -2
- package/build/cjs/components/CardBase/CardBase.d.ts +1 -0
- package/build/cjs/components/CardBase/CardBase.js +2 -5
- package/build/cjs/components/Image/Image.js +1 -2
- package/build/cjs/components/Media/Video/Video.js +1 -1
- package/build/cjs/components/ReactPlayer/ReactPlayer.d.ts +2 -1
- package/build/cjs/components/ReactPlayer/ReactPlayer.js +13 -3
- package/build/cjs/models/components.d.ts +1 -2
- package/build/cjs/models/constructor-items/common.d.ts +1 -1
- package/build/cjs/models/constructor-items/sub-blocks.d.ts +1 -1
- package/build/cjs/schema/constants.d.ts +24 -4
- package/build/cjs/schema/validators/common.d.ts +12 -2
- package/build/cjs/schema/validators/common.js +1 -4
- package/build/cjs/sub-blocks/Quote/Quote.js +2 -1
- package/build/cjs/sub-blocks/Quote/schema.d.ts +24 -4
- package/build/cjs/sub-blocks/Quote/schema.js +1 -4
- package/build/cjs/text-transform/transformers.js +3 -1
- package/build/esm/blocks/Header/Header.css +3 -0
- package/build/esm/blocks/Share/Share.js +5 -1
- package/build/esm/blocks/Share/i18n/en.json +11 -1
- package/build/esm/blocks/Share/i18n/ru.json +11 -1
- package/build/esm/components/Author/Author.js +7 -1
- package/build/esm/components/Author/schema.d.ts +12 -2
- package/build/esm/components/CardBase/CardBase.d.ts +1 -0
- package/build/esm/components/CardBase/CardBase.js +2 -5
- package/build/esm/components/Image/Image.js +1 -2
- package/build/esm/components/Media/Video/Video.js +1 -1
- package/build/esm/components/ReactPlayer/ReactPlayer.d.ts +2 -1
- package/build/esm/components/ReactPlayer/ReactPlayer.js +13 -3
- package/build/esm/models/components.d.ts +1 -2
- package/build/esm/models/constructor-items/common.d.ts +1 -1
- package/build/esm/models/constructor-items/sub-blocks.d.ts +1 -1
- package/build/esm/schema/constants.d.ts +24 -4
- package/build/esm/schema/validators/common.d.ts +12 -2
- package/build/esm/schema/validators/common.js +2 -5
- package/build/esm/sub-blocks/Quote/Quote.js +2 -1
- package/build/esm/sub-blocks/Quote/schema.d.ts +24 -4
- package/build/esm/sub-blocks/Quote/schema.js +2 -5
- package/build/esm/text-transform/transformers.js +3 -1
- package/package.json +1 -1
- package/server/models/components.d.ts +1 -2
- package/server/models/constructor-items/common.d.ts +1 -1
- package/server/models/constructor-items/sub-blocks.d.ts +1 -1
- package/server/text-transform/transformers.js +3 -1
- package/widget/index.js +1 -1
- package/build/cjs/components/Image/i18n/en.json +0 -3
- package/build/cjs/components/Image/i18n/index.d.ts +0 -2
- package/build/cjs/components/Image/i18n/index.js +0 -8
- package/build/cjs/components/Image/i18n/ru.json +0 -3
- package/build/esm/components/Image/i18n/en.json +0 -3
- package/build/esm/components/Image/i18n/index.d.ts +0 -2
- package/build/esm/components/Image/i18n/index.js +0 -5
- package/build/esm/components/Image/i18n/ru.json +0 -3
|
@@ -20,6 +20,9 @@ unpredictable css rules order in build */
|
|
|
20
20
|
position: relative;
|
|
21
21
|
height: 100%;
|
|
22
22
|
}
|
|
23
|
+
.pc-header-block__content_theme_dark {
|
|
24
|
+
--g-color-line-focus: var(--pc-color-line-focus-dark);
|
|
25
|
+
}
|
|
23
26
|
.pc-header-block__content_theme_dark .pc-header-block__title,
|
|
24
27
|
.pc-header-block__content_theme_dark .pc-header-block__overtitle {
|
|
25
28
|
color: var(--g-color-text-light-primary);
|
|
@@ -31,7 +31,11 @@ const Share = ({ items, title }) => {
|
|
|
31
31
|
const url = (0, utils_1.getAbsolutePath)(hostname, pathname);
|
|
32
32
|
const socialUrl = (0, utils_1.getShareLink)(url, type);
|
|
33
33
|
const icon = icons[type];
|
|
34
|
-
|
|
34
|
+
const urlTitle = (0, i18n_1.default)(`${type}-title`);
|
|
35
|
+
const buttonLabel = (0, i18n_1.default)(`${type}-label`);
|
|
36
|
+
return (react_1.default.createElement(uikit_1.Button, { key: type, view: "flat", size: "l", target: "_blank", href: socialUrl, className: b('item', { type: type.toLowerCase() }), onClick: handleButtonClick, title: urlTitle, extraProps: {
|
|
37
|
+
'aria-label': buttonLabel,
|
|
38
|
+
} }, icon && react_1.default.createElement(uikit_1.Icon, { data: icon, size: 24, className: b('icon', { type }) })));
|
|
35
39
|
}))));
|
|
36
40
|
};
|
|
37
41
|
exports.default = Share;
|
|
@@ -1,3 +1,13 @@
|
|
|
1
1
|
{
|
|
2
|
-
"constructor-share": "Share"
|
|
2
|
+
"constructor-share": "Share",
|
|
3
|
+
"facebook-title": "Opens in a new tab",
|
|
4
|
+
"twitter-title": "Opens in a new tab",
|
|
5
|
+
"linkedin-title": "Opens in a new tab",
|
|
6
|
+
"vk-title": "Opens in a new tab",
|
|
7
|
+
"telegram-title": "Opens in a new tab",
|
|
8
|
+
"facebook-label": "Facebook logo",
|
|
9
|
+
"twitter-label": "Twitter logo",
|
|
10
|
+
"linkedin-label": "LinkedIn logo",
|
|
11
|
+
"vk-label": "VK logo",
|
|
12
|
+
"telegram-label": "Telegram logo"
|
|
3
13
|
}
|
|
@@ -1,3 +1,13 @@
|
|
|
1
1
|
{
|
|
2
|
-
"constructor-share": "Поделиться"
|
|
2
|
+
"constructor-share": "Поделиться",
|
|
3
|
+
"facebook-title": "Откроется в новой вкладке",
|
|
4
|
+
"twitter-title": "Откроется в новой вкладке",
|
|
5
|
+
"linkedin-title": "Откроется в новой вкладке",
|
|
6
|
+
"vk-title": "Откроется в новой вкладке",
|
|
7
|
+
"telegram-title": "Откроется в новой вкладке",
|
|
8
|
+
"facebook-label": "Facebook лого",
|
|
9
|
+
"twitter-label": "Twitter лого",
|
|
10
|
+
"linkedin-label": "LinkedIn лого",
|
|
11
|
+
"vk-label": "VK лого",
|
|
12
|
+
"telegram-label": "Telegram лого"
|
|
3
13
|
}
|
|
@@ -4,14 +4,20 @@ const tslib_1 = require("tslib");
|
|
|
4
4
|
const react_1 = tslib_1.__importDefault(require("react"));
|
|
5
5
|
const models_1 = require("../../models");
|
|
6
6
|
const utils_1 = require("../../utils");
|
|
7
|
+
const utils_2 = require("../Media/Image/utils");
|
|
7
8
|
const index_1 = require("../index");
|
|
8
9
|
const b = (0, utils_1.block)('author');
|
|
9
10
|
const Author = (props) => {
|
|
10
11
|
const { author, className, authorContainerClassName, type = models_1.AuthorType.Column, qa } = props;
|
|
11
12
|
const { firstName, secondName, description, avatar } = author;
|
|
12
13
|
const name = secondName ? `${firstName} ${secondName}` : firstName;
|
|
14
|
+
const isAvatarJSX = react_1.default.isValidElement(avatar);
|
|
15
|
+
let avatarProps = {};
|
|
16
|
+
if (!isAvatarJSX && avatar) {
|
|
17
|
+
avatarProps = (0, utils_2.getMediaImage)(avatar);
|
|
18
|
+
}
|
|
13
19
|
return (react_1.default.createElement("div", { className: b({ type }, className), "data-qa": qa },
|
|
14
|
-
avatar && (react_1.default.createElement("div", { className: b('avatar', authorContainerClassName) },
|
|
20
|
+
avatar && (react_1.default.createElement("div", { className: b('avatar', authorContainerClassName) }, isAvatarJSX ? avatar : react_1.default.createElement(index_1.Image, Object.assign({}, avatarProps)))),
|
|
15
21
|
react_1.default.createElement("div", { className: b('label') },
|
|
16
22
|
react_1.default.createElement("div", { className: b('name') }, name),
|
|
17
23
|
description && react_1.default.createElement("div", { className: b('description') }, description))));
|
|
@@ -17,8 +17,18 @@ export declare const author: {
|
|
|
17
17
|
contentType: string;
|
|
18
18
|
};
|
|
19
19
|
avatar: {
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
oneOf: ({
|
|
21
|
+
type: string;
|
|
22
|
+
properties: {
|
|
23
|
+
when: {
|
|
24
|
+
type: string;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
} | {
|
|
28
|
+
type: string;
|
|
29
|
+
pattern: string;
|
|
30
|
+
optionName: string;
|
|
31
|
+
})[];
|
|
22
32
|
};
|
|
23
33
|
description: {
|
|
24
34
|
type: string;
|
|
@@ -11,6 +11,7 @@ export interface CardBaseProps extends AnalyticsEventsBase, CardBaseParams {
|
|
|
11
11
|
metrikaGoals?: MetrikaGoal;
|
|
12
12
|
pixelEvents?: ButtonPixel;
|
|
13
13
|
qa?: string;
|
|
14
|
+
extraProps?: React.HTMLAttributes<HTMLElement>;
|
|
14
15
|
}
|
|
15
16
|
export interface CardHeaderBaseProps {
|
|
16
17
|
className?: string;
|
|
@@ -15,7 +15,7 @@ const Header = () => null;
|
|
|
15
15
|
const Content = () => null;
|
|
16
16
|
const Footer = () => null;
|
|
17
17
|
const Layout = (props) => {
|
|
18
|
-
const { className, bodyClassName, metrikaGoals, pixelEvents, analyticsEvents, contentClassName, children, url, target, border = 'shadow', urlTitle, qa, } = props;
|
|
18
|
+
const { className, bodyClassName, metrikaGoals, pixelEvents, analyticsEvents, contentClassName, children, url, target, border = 'shadow', urlTitle, qa, extraProps = {}, } = props;
|
|
19
19
|
const handleMetrika = (0, useMetrika_1.useMetrika)();
|
|
20
20
|
const handleAnalytics = (0, hooks_1.useAnalytics)(models_1.DefaultEventNames.CardBase, url);
|
|
21
21
|
let header, content, footer, image, headerClass, footerClass;
|
|
@@ -54,10 +54,7 @@ const Layout = (props) => {
|
|
|
54
54
|
handleAnalytics(analyticsEvents);
|
|
55
55
|
};
|
|
56
56
|
return url ? (react_1.default.createElement(RouterLink_1.default, { href: url },
|
|
57
|
-
react_1.default.createElement(uikit_1.Link, { href: url, target: target, rel: target === '_blank' ? 'noopener noreferrer' : undefined, className: fullClassName, onClick: onClick, title: urlTitle, extraProps: {
|
|
58
|
-
draggable: false,
|
|
59
|
-
onDragStart: (e) => e.preventDefault(),
|
|
60
|
-
}, qa: qa }, cardContent))) : (react_1.default.createElement("div", { className: fullClassName, "data-qa": qa }, cardContent));
|
|
57
|
+
react_1.default.createElement(uikit_1.Link, { href: url, target: target, rel: target === '_blank' ? 'noopener noreferrer' : undefined, className: fullClassName, onClick: onClick, title: urlTitle, extraProps: Object.assign({ draggable: false, onDragStart: (e) => e.preventDefault() }, extraProps), qa: qa }, cardContent))) : (react_1.default.createElement("div", Object.assign({ className: fullClassName, "data-qa": qa }, extraProps), cardContent));
|
|
61
58
|
};
|
|
62
59
|
exports.Layout = Layout;
|
|
63
60
|
exports.Layout.Header = Header;
|
|
@@ -7,7 +7,6 @@ const projectSettingsContext_1 = require("../../context/projectSettingsContext")
|
|
|
7
7
|
const utils_1 = require("../../utils");
|
|
8
8
|
const imageCompress_1 = require("../../utils/imageCompress");
|
|
9
9
|
const ImageBase_1 = tslib_1.__importDefault(require("../ImageBase/ImageBase"));
|
|
10
|
-
const i18n_1 = tslib_1.__importDefault(require("./i18n"));
|
|
11
10
|
const checkWebP = (src) => {
|
|
12
11
|
return src.endsWith('.webp') ? src : src + '.webp';
|
|
13
12
|
};
|
|
@@ -16,7 +15,7 @@ const DeviceSpecificFragment = ({ disableWebp, src, breakpoint, qa, }) => (react
|
|
|
16
15
|
react_1.default.createElement("source", { srcSet: src, media: `(max-width: ${breakpoint}px)`, "data-qa": qa })));
|
|
17
16
|
const Image = (props) => {
|
|
18
17
|
const projectSettings = (0, react_1.useContext)(projectSettingsContext_1.ProjectSettingsContext);
|
|
19
|
-
const { src: imageSrc, alt
|
|
18
|
+
const { src: imageSrc, alt, disableCompress, tablet, desktop, mobile, style, className, onClick, containerClassName, qa, } = props;
|
|
20
19
|
const [imgLoadingError, setImgLoadingError] = (0, react_1.useState)(false);
|
|
21
20
|
const src = imageSrc || desktop;
|
|
22
21
|
if (!src) {
|
|
@@ -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, ratio: ratio }));
|
|
35
|
+
return (react_1.default.createElement(ReactPlayer_1.default, { ref: ref, 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,
|
|
@@ -11,5 +11,6 @@ export interface ReactPlayerBlockProps extends Omit<MediaVideoProps, 'loop' | 's
|
|
|
11
11
|
ratio?: number;
|
|
12
12
|
children?: React.ReactNode;
|
|
13
13
|
}
|
|
14
|
-
|
|
14
|
+
type ReactPlayerBlockRefType = ReactPlayerBlockHandler | undefined;
|
|
15
|
+
export declare const ReactPlayerBlock: React.ForwardRefExoticComponent<ReactPlayerBlockProps & React.RefAttributes<ReactPlayerBlockRefType>>;
|
|
15
16
|
export default ReactPlayerBlock;
|
|
@@ -48,9 +48,19 @@ exports.ReactPlayerBlock = react_1.default.forwardRef((props, originRef) => {
|
|
|
48
48
|
return [];
|
|
49
49
|
}, [analyticsEvents]);
|
|
50
50
|
const handleAnalytics = (0, hooks_1.useAnalytics)(models_1.DefaultEventNames.ReactPlayerControls);
|
|
51
|
-
(0, react_1.useImperativeHandle)(originRef, () =>
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
(0, react_1.useImperativeHandle)(originRef, () => {
|
|
52
|
+
if (!playerRef) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const videoInstance = playerRef.getInternalPlayer();
|
|
56
|
+
const { play, pause, addEventListener } = videoInstance;
|
|
57
|
+
// eslint-disable-next-line consistent-return
|
|
58
|
+
return {
|
|
59
|
+
play: play.bind(videoInstance),
|
|
60
|
+
pause: pause.bind(videoInstance),
|
|
61
|
+
addEventListener: addEventListener.bind(videoInstance),
|
|
62
|
+
};
|
|
63
|
+
}, [playerRef]);
|
|
54
64
|
(0, react_1.useEffect)(() => {
|
|
55
65
|
if (ref.current && !(playingVideoRef === null || playingVideoRef === void 0 ? void 0 : playingVideoRef.contains(ref.current))) {
|
|
56
66
|
setMuted(true);
|
|
@@ -251,7 +251,7 @@ export interface AuthorItem {
|
|
|
251
251
|
firstName: string;
|
|
252
252
|
secondName: string;
|
|
253
253
|
description?: string;
|
|
254
|
-
avatar?:
|
|
254
|
+
avatar?: ImageProps | JSX.Element;
|
|
255
255
|
}
|
|
256
256
|
export interface HeaderBreadCrumbsProps extends ClassNameProps {
|
|
257
257
|
items: {
|
|
@@ -64,7 +64,7 @@ export interface HubspotFormProps extends HubspotEventHandlers, AnalyticsEventsB
|
|
|
64
64
|
export interface QuoteProps extends Themable, CardBaseProps {
|
|
65
65
|
text: string;
|
|
66
66
|
image: ThemedImage;
|
|
67
|
-
logo:
|
|
67
|
+
logo: ImageProps;
|
|
68
68
|
color?: string;
|
|
69
69
|
url?: string;
|
|
70
70
|
author?: AuthorItem;
|
|
@@ -144,8 +144,18 @@ export declare const cardSchemas: {
|
|
|
144
144
|
})[];
|
|
145
145
|
};
|
|
146
146
|
logo: {
|
|
147
|
-
|
|
148
|
-
|
|
147
|
+
oneOf: ({
|
|
148
|
+
type: string;
|
|
149
|
+
properties: {
|
|
150
|
+
when: {
|
|
151
|
+
type: string;
|
|
152
|
+
};
|
|
153
|
+
};
|
|
154
|
+
} | {
|
|
155
|
+
type: string;
|
|
156
|
+
pattern: string;
|
|
157
|
+
optionName: string;
|
|
158
|
+
})[];
|
|
149
159
|
};
|
|
150
160
|
color: {
|
|
151
161
|
type: string;
|
|
@@ -173,8 +183,18 @@ export declare const cardSchemas: {
|
|
|
173
183
|
contentType: string;
|
|
174
184
|
};
|
|
175
185
|
avatar: {
|
|
176
|
-
|
|
177
|
-
|
|
186
|
+
oneOf: ({
|
|
187
|
+
type: string;
|
|
188
|
+
properties: {
|
|
189
|
+
when: {
|
|
190
|
+
type: string;
|
|
191
|
+
};
|
|
192
|
+
};
|
|
193
|
+
} | {
|
|
194
|
+
type: string;
|
|
195
|
+
pattern: string;
|
|
196
|
+
optionName: string;
|
|
197
|
+
})[];
|
|
178
198
|
};
|
|
179
199
|
description: {
|
|
180
200
|
type: string;
|
|
@@ -517,8 +517,18 @@ export declare const authorItem: {
|
|
|
517
517
|
contentType: string;
|
|
518
518
|
};
|
|
519
519
|
avatar: {
|
|
520
|
-
|
|
521
|
-
|
|
520
|
+
oneOf: ({
|
|
521
|
+
type: string;
|
|
522
|
+
properties: {
|
|
523
|
+
when: {
|
|
524
|
+
type: string;
|
|
525
|
+
};
|
|
526
|
+
};
|
|
527
|
+
} | {
|
|
528
|
+
type: string;
|
|
529
|
+
pattern: string;
|
|
530
|
+
optionName: string;
|
|
531
|
+
})[];
|
|
522
532
|
};
|
|
523
533
|
description: {
|
|
524
534
|
type: string;
|
|
@@ -270,10 +270,7 @@ exports.authorItem = {
|
|
|
270
270
|
type: 'string',
|
|
271
271
|
contentType: 'text',
|
|
272
272
|
},
|
|
273
|
-
avatar:
|
|
274
|
-
type: 'string',
|
|
275
|
-
pattern: schema_1.imageUrlPattern,
|
|
276
|
-
},
|
|
273
|
+
avatar: schema_1.ImageProps,
|
|
277
274
|
description: {
|
|
278
275
|
type: 'string',
|
|
279
276
|
contentType: 'yfm',
|
|
@@ -20,10 +20,11 @@ const Quote = (props) => {
|
|
|
20
20
|
const renderFooter = Boolean(author || url) && (react_1.default.createElement("div", { className: b('author-wrapper') },
|
|
21
21
|
author && (react_1.default.createElement(components_1.Author, { className: b('author', { theme: textTheme }), author: author, type: models_1.AuthorType.Line })),
|
|
22
22
|
url && buttonText && (react_1.default.createElement(uikit_1.Button, { view: "outlined", size: "xl", href: url, className: b('link-button', { theme: textTheme }), onClick: handleButtonClick }, buttonText))));
|
|
23
|
+
const logoProps = (0, utils_1.getMediaImage)(logo);
|
|
23
24
|
return (react_1.default.createElement("div", { className: b({ theme: textTheme, border }), style: color ? { backgroundColor: color } : {} },
|
|
24
25
|
react_1.default.createElement("div", { key: text, className: b('content-wrapper') },
|
|
25
26
|
react_1.default.createElement("div", null,
|
|
26
|
-
react_1.default.createElement(components_1.Image, { className: b('logo'),
|
|
27
|
+
react_1.default.createElement(components_1.Image, Object.assign({ className: b('logo') }, logoProps)),
|
|
27
28
|
react_1.default.createElement("div", { className: b('content') },
|
|
28
29
|
react_1.default.createElement("span", { className: b('text') },
|
|
29
30
|
react_1.default.createElement(components_1.HTML, null, text)))),
|
|
@@ -32,8 +32,18 @@ export declare const Quote: {
|
|
|
32
32
|
})[];
|
|
33
33
|
};
|
|
34
34
|
logo: {
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
oneOf: ({
|
|
36
|
+
type: string;
|
|
37
|
+
properties: {
|
|
38
|
+
when: {
|
|
39
|
+
type: string;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
} | {
|
|
43
|
+
type: string;
|
|
44
|
+
pattern: string;
|
|
45
|
+
optionName: string;
|
|
46
|
+
})[];
|
|
37
47
|
};
|
|
38
48
|
color: {
|
|
39
49
|
type: string;
|
|
@@ -61,8 +71,18 @@ export declare const Quote: {
|
|
|
61
71
|
contentType: string;
|
|
62
72
|
};
|
|
63
73
|
avatar: {
|
|
64
|
-
|
|
65
|
-
|
|
74
|
+
oneOf: ({
|
|
75
|
+
type: string;
|
|
76
|
+
properties: {
|
|
77
|
+
when: {
|
|
78
|
+
type: string;
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
} | {
|
|
82
|
+
type: string;
|
|
83
|
+
pattern: string;
|
|
84
|
+
optionName: string;
|
|
85
|
+
})[];
|
|
66
86
|
};
|
|
67
87
|
description: {
|
|
68
88
|
type: string;
|
|
@@ -10,10 +10,7 @@ exports.Quote = {
|
|
|
10
10
|
properties: Object.assign(Object.assign({}, common_1.BaseProps), { text: {
|
|
11
11
|
type: 'string',
|
|
12
12
|
contentType: 'text',
|
|
13
|
-
}, image: (0, common_1.withTheme)(schema_1.ImageProps), logo: {
|
|
14
|
-
type: 'string',
|
|
15
|
-
pattern: schema_1.imageUrlPattern,
|
|
16
|
-
}, color: {
|
|
13
|
+
}, image: (0, common_1.withTheme)(schema_1.ImageProps), logo: schema_1.ImageProps, color: {
|
|
17
14
|
type: 'string',
|
|
18
15
|
}, url: {
|
|
19
16
|
type: 'string',
|
|
@@ -44,7 +44,9 @@ function transformBlock(lang, blocksConfig, block, plugins) {
|
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
46
|
if ('children' in block && block.children) {
|
|
47
|
-
block.children = transformBlocks(block.children, lang, blocksConfig
|
|
47
|
+
block.children = transformBlocks(block.children, lang, blocksConfig, {
|
|
48
|
+
plugins,
|
|
49
|
+
});
|
|
48
50
|
}
|
|
49
51
|
return block;
|
|
50
52
|
}
|
|
@@ -20,6 +20,9 @@ unpredictable css rules order in build */
|
|
|
20
20
|
position: relative;
|
|
21
21
|
height: 100%;
|
|
22
22
|
}
|
|
23
|
+
.pc-header-block__content_theme_dark {
|
|
24
|
+
--g-color-line-focus: var(--pc-color-line-focus-dark);
|
|
25
|
+
}
|
|
23
26
|
.pc-header-block__content_theme_dark .pc-header-block__title,
|
|
24
27
|
.pc-header-block__content_theme_dark .pc-header-block__overtitle {
|
|
25
28
|
color: var(--g-color-text-light-primary);
|
|
@@ -29,7 +29,11 @@ const Share = ({ items, title }) => {
|
|
|
29
29
|
const url = getAbsolutePath(hostname, pathname);
|
|
30
30
|
const socialUrl = getShareLink(url, type);
|
|
31
31
|
const icon = icons[type];
|
|
32
|
-
|
|
32
|
+
const urlTitle = i18n(`${type}-title`);
|
|
33
|
+
const buttonLabel = i18n(`${type}-label`);
|
|
34
|
+
return (React.createElement(Button, { key: type, view: "flat", size: "l", target: "_blank", href: socialUrl, className: b('item', { type: type.toLowerCase() }), onClick: handleButtonClick, title: urlTitle, extraProps: {
|
|
35
|
+
'aria-label': buttonLabel,
|
|
36
|
+
} }, icon && React.createElement(Icon, { data: icon, size: 24, className: b('icon', { type }) })));
|
|
33
37
|
}))));
|
|
34
38
|
};
|
|
35
39
|
export default Share;
|
|
@@ -1,3 +1,13 @@
|
|
|
1
1
|
{
|
|
2
|
-
"constructor-share": "Share"
|
|
2
|
+
"constructor-share": "Share",
|
|
3
|
+
"facebook-title": "Opens in a new tab",
|
|
4
|
+
"twitter-title": "Opens in a new tab",
|
|
5
|
+
"linkedin-title": "Opens in a new tab",
|
|
6
|
+
"vk-title": "Opens in a new tab",
|
|
7
|
+
"telegram-title": "Opens in a new tab",
|
|
8
|
+
"facebook-label": "Facebook logo",
|
|
9
|
+
"twitter-label": "Twitter logo",
|
|
10
|
+
"linkedin-label": "LinkedIn logo",
|
|
11
|
+
"vk-label": "VK logo",
|
|
12
|
+
"telegram-label": "Telegram logo"
|
|
3
13
|
}
|
|
@@ -1,3 +1,13 @@
|
|
|
1
1
|
{
|
|
2
|
-
"constructor-share": "Поделиться"
|
|
2
|
+
"constructor-share": "Поделиться",
|
|
3
|
+
"facebook-title": "Откроется в новой вкладке",
|
|
4
|
+
"twitter-title": "Откроется в новой вкладке",
|
|
5
|
+
"linkedin-title": "Откроется в новой вкладке",
|
|
6
|
+
"vk-title": "Откроется в новой вкладке",
|
|
7
|
+
"telegram-title": "Откроется в новой вкладке",
|
|
8
|
+
"facebook-label": "Facebook лого",
|
|
9
|
+
"twitter-label": "Twitter лого",
|
|
10
|
+
"linkedin-label": "LinkedIn лого",
|
|
11
|
+
"vk-label": "VK лого",
|
|
12
|
+
"telegram-label": "Telegram лого"
|
|
3
13
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { AuthorType } from '../../models';
|
|
3
3
|
import { block } from '../../utils';
|
|
4
|
+
import { getMediaImage } from '../Media/Image/utils';
|
|
4
5
|
import { Image } from '../index';
|
|
5
6
|
import './Author.css';
|
|
6
7
|
const b = block('author');
|
|
@@ -8,8 +9,13 @@ const Author = (props) => {
|
|
|
8
9
|
const { author, className, authorContainerClassName, type = AuthorType.Column, qa } = props;
|
|
9
10
|
const { firstName, secondName, description, avatar } = author;
|
|
10
11
|
const name = secondName ? `${firstName} ${secondName}` : firstName;
|
|
12
|
+
const isAvatarJSX = React.isValidElement(avatar);
|
|
13
|
+
let avatarProps = {};
|
|
14
|
+
if (!isAvatarJSX && avatar) {
|
|
15
|
+
avatarProps = getMediaImage(avatar);
|
|
16
|
+
}
|
|
11
17
|
return (React.createElement("div", { className: b({ type }, className), "data-qa": qa },
|
|
12
|
-
avatar && (React.createElement("div", { className: b('avatar', authorContainerClassName) },
|
|
18
|
+
avatar && (React.createElement("div", { className: b('avatar', authorContainerClassName) }, isAvatarJSX ? avatar : React.createElement(Image, Object.assign({}, avatarProps)))),
|
|
13
19
|
React.createElement("div", { className: b('label') },
|
|
14
20
|
React.createElement("div", { className: b('name') }, name),
|
|
15
21
|
description && React.createElement("div", { className: b('description') }, description))));
|
|
@@ -17,8 +17,18 @@ export declare const author: {
|
|
|
17
17
|
contentType: string;
|
|
18
18
|
};
|
|
19
19
|
avatar: {
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
oneOf: ({
|
|
21
|
+
type: string;
|
|
22
|
+
properties: {
|
|
23
|
+
when: {
|
|
24
|
+
type: string;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
} | {
|
|
28
|
+
type: string;
|
|
29
|
+
pattern: string;
|
|
30
|
+
optionName: string;
|
|
31
|
+
})[];
|
|
22
32
|
};
|
|
23
33
|
description: {
|
|
24
34
|
type: string;
|
|
@@ -12,6 +12,7 @@ export interface CardBaseProps extends AnalyticsEventsBase, CardBaseParams {
|
|
|
12
12
|
metrikaGoals?: MetrikaGoal;
|
|
13
13
|
pixelEvents?: ButtonPixel;
|
|
14
14
|
qa?: string;
|
|
15
|
+
extraProps?: React.HTMLAttributes<HTMLElement>;
|
|
15
16
|
}
|
|
16
17
|
export interface CardHeaderBaseProps {
|
|
17
18
|
className?: string;
|
|
@@ -12,7 +12,7 @@ const Header = () => null;
|
|
|
12
12
|
const Content = () => null;
|
|
13
13
|
const Footer = () => null;
|
|
14
14
|
export const Layout = (props) => {
|
|
15
|
-
const { className, bodyClassName, metrikaGoals, pixelEvents, analyticsEvents, contentClassName, children, url, target, border = 'shadow', urlTitle, qa, } = props;
|
|
15
|
+
const { className, bodyClassName, metrikaGoals, pixelEvents, analyticsEvents, contentClassName, children, url, target, border = 'shadow', urlTitle, qa, extraProps = {}, } = props;
|
|
16
16
|
const handleMetrika = useMetrika();
|
|
17
17
|
const handleAnalytics = useAnalytics(DefaultEventNames.CardBase, url);
|
|
18
18
|
let header, content, footer, image, headerClass, footerClass;
|
|
@@ -51,10 +51,7 @@ export const Layout = (props) => {
|
|
|
51
51
|
handleAnalytics(analyticsEvents);
|
|
52
52
|
};
|
|
53
53
|
return url ? (React.createElement(RouterLink, { href: url },
|
|
54
|
-
React.createElement(Link, { href: url, target: target, rel: target === '_blank' ? 'noopener noreferrer' : undefined, className: fullClassName, onClick: onClick, title: urlTitle, extraProps: {
|
|
55
|
-
draggable: false,
|
|
56
|
-
onDragStart: (e) => e.preventDefault(),
|
|
57
|
-
}, qa: qa }, cardContent))) : (React.createElement("div", { className: fullClassName, "data-qa": qa }, cardContent));
|
|
54
|
+
React.createElement(Link, { href: url, target: target, rel: target === '_blank' ? 'noopener noreferrer' : undefined, className: fullClassName, onClick: onClick, title: urlTitle, extraProps: Object.assign({ draggable: false, onDragStart: (e) => e.preventDefault() }, extraProps), qa: qa }, cardContent))) : (React.createElement("div", Object.assign({ className: fullClassName, "data-qa": qa }, extraProps), cardContent));
|
|
58
55
|
};
|
|
59
56
|
Layout.Header = Header;
|
|
60
57
|
Layout.Content = Content;
|
|
@@ -4,7 +4,6 @@ import { ProjectSettingsContext } from '../../context/projectSettingsContext';
|
|
|
4
4
|
import { getQaAttrubutes } from '../../utils';
|
|
5
5
|
import { isCompressible } from '../../utils/imageCompress';
|
|
6
6
|
import ImageBase from '../ImageBase/ImageBase';
|
|
7
|
-
import i18n from './i18n';
|
|
8
7
|
const checkWebP = (src) => {
|
|
9
8
|
return src.endsWith('.webp') ? src : src + '.webp';
|
|
10
9
|
};
|
|
@@ -13,7 +12,7 @@ const DeviceSpecificFragment = ({ disableWebp, src, breakpoint, qa, }) => (React
|
|
|
13
12
|
React.createElement("source", { srcSet: src, media: `(max-width: ${breakpoint}px)`, "data-qa": qa })));
|
|
14
13
|
const Image = (props) => {
|
|
15
14
|
const projectSettings = useContext(ProjectSettingsContext);
|
|
16
|
-
const { src: imageSrc, alt
|
|
15
|
+
const { src: imageSrc, alt, disableCompress, tablet, desktop, mobile, style, className, onClick, containerClassName, qa, } = props;
|
|
17
16
|
const [imgLoadingError, setImgLoadingError] = useState(false);
|
|
18
17
|
const src = imageSrc || desktop;
|
|
19
18
|
if (!src) {
|
|
@@ -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, ratio: ratio }));
|
|
33
|
+
return (React.createElement(ReactPlayerBlock, { ref: ref, 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,
|
|
@@ -12,5 +12,6 @@ export interface ReactPlayerBlockProps extends Omit<MediaVideoProps, 'loop' | 's
|
|
|
12
12
|
ratio?: number;
|
|
13
13
|
children?: React.ReactNode;
|
|
14
14
|
}
|
|
15
|
-
|
|
15
|
+
type ReactPlayerBlockRefType = ReactPlayerBlockHandler | undefined;
|
|
16
|
+
export declare const ReactPlayerBlock: React.ForwardRefExoticComponent<ReactPlayerBlockProps & React.RefAttributes<ReactPlayerBlockRefType>>;
|
|
16
17
|
export default ReactPlayerBlock;
|
|
@@ -45,9 +45,19 @@ export const ReactPlayerBlock = React.forwardRef((props, originRef) => {
|
|
|
45
45
|
return [];
|
|
46
46
|
}, [analyticsEvents]);
|
|
47
47
|
const handleAnalytics = useAnalytics(DefaultEventNames.ReactPlayerControls);
|
|
48
|
-
useImperativeHandle(originRef, () =>
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
useImperativeHandle(originRef, () => {
|
|
49
|
+
if (!playerRef) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const videoInstance = playerRef.getInternalPlayer();
|
|
53
|
+
const { play, pause, addEventListener } = videoInstance;
|
|
54
|
+
// eslint-disable-next-line consistent-return
|
|
55
|
+
return {
|
|
56
|
+
play: play.bind(videoInstance),
|
|
57
|
+
pause: pause.bind(videoInstance),
|
|
58
|
+
addEventListener: addEventListener.bind(videoInstance),
|
|
59
|
+
};
|
|
60
|
+
}, [playerRef]);
|
|
51
61
|
useEffect(() => {
|
|
52
62
|
if (ref.current && !(playingVideoRef === null || playingVideoRef === void 0 ? void 0 : playingVideoRef.contains(ref.current))) {
|
|
53
63
|
setMuted(true);
|
|
@@ -251,7 +251,7 @@ export interface AuthorItem {
|
|
|
251
251
|
firstName: string;
|
|
252
252
|
secondName: string;
|
|
253
253
|
description?: string;
|
|
254
|
-
avatar?:
|
|
254
|
+
avatar?: ImageProps | JSX.Element;
|
|
255
255
|
}
|
|
256
256
|
export interface HeaderBreadCrumbsProps extends ClassNameProps {
|
|
257
257
|
items: {
|
|
@@ -64,7 +64,7 @@ export interface HubspotFormProps extends HubspotEventHandlers, AnalyticsEventsB
|
|
|
64
64
|
export interface QuoteProps extends Themable, CardBaseProps {
|
|
65
65
|
text: string;
|
|
66
66
|
image: ThemedImage;
|
|
67
|
-
logo:
|
|
67
|
+
logo: ImageProps;
|
|
68
68
|
color?: string;
|
|
69
69
|
url?: string;
|
|
70
70
|
author?: AuthorItem;
|