@gravity-ui/page-constructor 4.31.1 → 4.33.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.js +6 -2
- package/build/cjs/blocks/Tabs/Tabs.js +8 -1
- package/build/cjs/components/BackLink/BackLink.d.ts +3 -2
- package/build/cjs/components/BackLink/BackLink.js +2 -2
- package/build/cjs/components/Button/Button.d.ts +0 -1
- package/build/cjs/components/DefaultVideo/DefaultVideo.css +5 -0
- package/build/cjs/components/DefaultVideo/DefaultVideo.d.ts +11 -0
- package/build/cjs/components/DefaultVideo/DefaultVideo.js +60 -0
- package/build/cjs/components/FileLink/FileLink.js +2 -2
- package/build/cjs/components/FullscreenImage/FullscreenImage.d.ts +2 -1
- package/build/cjs/components/FullscreenImage/FullscreenImage.js +2 -2
- package/build/cjs/components/Image/Image.js +2 -2
- package/build/cjs/components/Link/Link.js +4 -4
- package/build/cjs/components/Media/Video/Video.css +0 -5
- package/build/cjs/components/Media/Video/Video.js +3 -7
- package/build/cjs/components/Title/Title.d.ts +2 -1
- package/build/cjs/components/Title/Title.js +2 -2
- package/build/cjs/components/Title/TitleItem.css +3 -3
- package/build/cjs/models/constructor-items/blocks.d.ts +2 -0
- package/build/cjs/models/constructor-items/common.d.ts +5 -2
- package/build/cjs/sub-blocks/BasicCard/BasicCard.js +5 -2
- package/build/cjs/sub-blocks/Content/Content.js +12 -5
- package/build/cjs/sub-blocks/HubspotForm/HubspotForm.css +10 -10
- package/build/cjs/sub-blocks/LayoutItem/utils.d.ts +1 -0
- package/build/cjs/sub-blocks/Quote/Quote.css +0 -2
- package/build/esm/blocks/Header/Header.js +6 -2
- package/build/esm/blocks/Tabs/Tabs.js +8 -1
- package/build/esm/components/BackLink/BackLink.d.ts +3 -2
- package/build/esm/components/BackLink/BackLink.js +2 -2
- package/build/esm/components/Button/Button.d.ts +0 -1
- package/build/esm/components/DefaultVideo/DefaultVideo.css +5 -0
- package/build/esm/components/DefaultVideo/DefaultVideo.d.ts +12 -0
- package/build/esm/components/DefaultVideo/DefaultVideo.js +57 -0
- package/build/esm/components/FileLink/FileLink.js +2 -2
- package/build/esm/components/FullscreenImage/FullscreenImage.d.ts +2 -1
- package/build/esm/components/FullscreenImage/FullscreenImage.js +2 -2
- package/build/esm/components/Image/Image.js +3 -2
- package/build/esm/components/Link/Link.js +4 -4
- package/build/esm/components/Media/Video/Video.css +0 -5
- package/build/esm/components/Media/Video/Video.js +3 -7
- package/build/esm/components/Title/Title.d.ts +2 -1
- package/build/esm/components/Title/Title.js +2 -2
- package/build/esm/components/Title/TitleItem.css +3 -3
- package/build/esm/models/constructor-items/blocks.d.ts +2 -0
- package/build/esm/models/constructor-items/common.d.ts +5 -2
- package/build/esm/sub-blocks/BasicCard/BasicCard.js +5 -2
- package/build/esm/sub-blocks/Content/Content.js +12 -5
- package/build/esm/sub-blocks/HubspotForm/HubspotForm.css +10 -10
- package/build/esm/sub-blocks/LayoutItem/utils.d.ts +1 -0
- package/build/esm/sub-blocks/Quote/Quote.css +0 -2
- package/package.json +1 -1
- package/server/models/constructor-items/blocks.d.ts +2 -0
- package/server/models/constructor-items/common.d.ts +5 -2
- package/widget/index.js +1 -1
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.HeaderBlock = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const react_1 = tslib_1.__importStar(require("react"));
|
|
6
|
+
const uikit_1 = require("@gravity-ui/uikit");
|
|
6
7
|
const components_1 = require("../../components");
|
|
7
8
|
const HeaderBreadcrumbs_1 = tslib_1.__importDefault(require("../../components/HeaderBreadcrumbs/HeaderBreadcrumbs"));
|
|
8
9
|
const utils_1 = require("../../components/Media/Image/utils");
|
|
@@ -35,6 +36,7 @@ const HeaderBlock = (props) => {
|
|
|
35
36
|
const imageThemed = image && (0, utils_2.getThemedValue)(image, theme);
|
|
36
37
|
const videoThemed = video && (0, utils_2.getThemedValue)(video, theme);
|
|
37
38
|
const fullWidth = (backgroundThemed === null || backgroundThemed === void 0 ? void 0 : backgroundThemed.fullWidth) || (backgroundThemed === null || backgroundThemed === void 0 ? void 0 : backgroundThemed.fullWidthMedia);
|
|
39
|
+
const titleId = (0, uikit_1.useUniqId)();
|
|
38
40
|
return (react_1.default.createElement("header", { className: b({
|
|
39
41
|
['has-media']: hasRightSideImage,
|
|
40
42
|
['full-width']: fullWidth,
|
|
@@ -57,7 +59,7 @@ const HeaderBlock = (props) => {
|
|
|
57
59
|
react_1.default.createElement(grid_1.Col, { sizes: titleSizes, className: b('content-inner') },
|
|
58
60
|
overtitle && (react_1.default.createElement("div", { className: b('overtitle') },
|
|
59
61
|
react_1.default.createElement(components_1.HTML, null, overtitle))),
|
|
60
|
-
react_1.default.createElement("h1", { className: b('title') },
|
|
62
|
+
react_1.default.createElement("h1", { className: b('title'), id: titleId },
|
|
61
63
|
status,
|
|
62
64
|
renderTitle ? renderTitle(title) : react_1.default.createElement(components_1.HTML, null, title)),
|
|
63
65
|
description && (react_1.default.createElement("div", { className: b('description') },
|
|
@@ -66,7 +68,9 @@ const HeaderBlock = (props) => {
|
|
|
66
68
|
constructorTheme: textTheme,
|
|
67
69
|
} }))),
|
|
68
70
|
buttons && (react_1.default.createElement("div", { className: b('buttons'), "data-qa": "header-buttons" }, buttons.map((button, index) => (react_1.default.createElement(components_1.RouterLink, { href: button.url, key: index },
|
|
69
|
-
react_1.default.createElement(components_1.Button, Object.assign({ key: index, className: b('button'), size: "xl"
|
|
71
|
+
react_1.default.createElement(components_1.Button, Object.assign({ key: index, className: b('button'), size: "xl", extraProps: {
|
|
72
|
+
'aria-describedby': titleId,
|
|
73
|
+
} }, button))))))),
|
|
70
74
|
children))),
|
|
71
75
|
hasRightSideImage && (react_1.default.createElement(components_1.Media, { className: b('media', { [curImageSize]: true }), videoClassName: b('video'), imageClassName: b('image'), video: videoThemed, image: imageThemed })))))));
|
|
72
76
|
};
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.TabsBlock = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const react_1 = tslib_1.__importStar(require("react"));
|
|
6
|
+
const uikit_1 = require("@gravity-ui/uikit");
|
|
6
7
|
const AnimateBlock_1 = tslib_1.__importDefault(require("../../components/AnimateBlock/AnimateBlock"));
|
|
7
8
|
const ButtonTabs_1 = tslib_1.__importDefault(require("../../components/ButtonTabs/ButtonTabs"));
|
|
8
9
|
const FullscreenImage_1 = tslib_1.__importDefault(require("../../components/FullscreenImage/FullscreenImage"));
|
|
@@ -26,10 +27,16 @@ const TabsBlock = ({ items, title, description, animated, tabsColSizes, centered
|
|
|
26
27
|
const ref = (0, react_1.useRef)(null);
|
|
27
28
|
const mediaWidth = (_a = ref === null || ref === void 0 ? void 0 : ref.current) === null || _a === void 0 ? void 0 : _a.offsetWidth;
|
|
28
29
|
const mediaHeight = mediaWidth && (0, VideoBlock_1.getHeight)(mediaWidth);
|
|
30
|
+
const captionId = (0, uikit_1.useUniqId)();
|
|
29
31
|
let imageProps;
|
|
30
32
|
if (activeTabData) {
|
|
31
33
|
const themedImage = (0, utils_2.getThemedValue)(activeTabData.image, theme);
|
|
32
34
|
imageProps = themedImage && (0, utils_1.getMediaImage)(themedImage);
|
|
35
|
+
if (activeTabData.caption && imageProps) {
|
|
36
|
+
Object.assign(imageProps, {
|
|
37
|
+
'aria-describedby': captionId,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
33
40
|
}
|
|
34
41
|
const showMedia = Boolean((activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.media) || imageProps);
|
|
35
42
|
const showText = Boolean(activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.text);
|
|
@@ -48,7 +55,7 @@ const TabsBlock = ({ items, title, description, animated, tabsColSizes, centered
|
|
|
48
55
|
react_1.default.createElement("div", { ref: ref }, (activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.media) && (react_1.default.createElement(Media_1.default, Object.assign({}, (0, utils_2.getThemedValue)(activeTabData.media, theme), { key: activeTab, className: b('media'), playVideo: play, height: mediaHeight })))),
|
|
49
56
|
imageProps && (react_1.default.createElement(react_1.Fragment, null,
|
|
50
57
|
react_1.default.createElement(FullscreenImage_1.default, Object.assign({}, imageProps, { imageClassName: b('image') })))),
|
|
51
|
-
(activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.caption) && react_1.default.createElement("p", { className: b('caption') }, activeTabData.caption)));
|
|
58
|
+
(activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.caption) && (react_1.default.createElement("p", { className: b('caption'), id: captionId }, activeTabData.caption))));
|
|
52
59
|
const onSelectTab = (id, e) => {
|
|
53
60
|
setActiveTab(id);
|
|
54
61
|
e.currentTarget.scrollIntoView({ inline: 'center', behavior: 'smooth', block: 'nearest' });
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { ReactNode } from 'react';
|
|
1
|
+
import { HTMLProps, ReactNode } from 'react';
|
|
2
2
|
import { ButtonSize } from '@gravity-ui/uikit';
|
|
3
3
|
import { Tabbable } from '../../models';
|
|
4
4
|
export type Theme = 'default' | 'special';
|
|
5
|
-
export interface BackLinkProps extends Tabbable {
|
|
5
|
+
export interface BackLinkProps<T = HTMLElement> extends Tabbable {
|
|
6
6
|
url: string;
|
|
7
7
|
title: ReactNode;
|
|
8
8
|
theme?: Theme;
|
|
@@ -10,5 +10,6 @@ export interface BackLinkProps extends Tabbable {
|
|
|
10
10
|
className?: string;
|
|
11
11
|
shouldHandleBackAction?: boolean;
|
|
12
12
|
onClick?: () => void;
|
|
13
|
+
extraProps?: HTMLProps<T>;
|
|
13
14
|
}
|
|
14
15
|
export default function BackLink(props: BackLinkProps): JSX.Element;
|
|
@@ -9,7 +9,7 @@ const icons_1 = require("../../icons");
|
|
|
9
9
|
const models_1 = require("../../models");
|
|
10
10
|
function BackLink(props) {
|
|
11
11
|
const { history } = (0, react_1.useContext)(locationContext_1.LocationContext);
|
|
12
|
-
const { url, title, theme = 'default', size = 'l', className, shouldHandleBackAction = false, onClick, tabIndex, } = props;
|
|
12
|
+
const { url, title, theme = 'default', size = 'l', className, shouldHandleBackAction = false, onClick, tabIndex, extraProps, } = props;
|
|
13
13
|
const handleAnalytics = (0, hooks_1.useAnalytics)(models_1.DefaultEventNames.ShareButton, url);
|
|
14
14
|
const backActionHandler = (0, react_1.useCallback)(async () => {
|
|
15
15
|
handleAnalytics();
|
|
@@ -26,7 +26,7 @@ function BackLink(props) {
|
|
|
26
26
|
history.push({ pathname: url });
|
|
27
27
|
}
|
|
28
28
|
}, [handleAnalytics, history, onClick, url]);
|
|
29
|
-
return (react_1.default.createElement(uikit_1.Button, { className: className, view: theme === 'special' ? 'flat-contrast' : 'flat-secondary', size: size, href: shouldHandleBackAction ? undefined : url, onClick: shouldHandleBackAction ? backActionHandler : undefined, tabIndex: tabIndex },
|
|
29
|
+
return (react_1.default.createElement(uikit_1.Button, { className: className, view: theme === 'special' ? 'flat-contrast' : 'flat-secondary', size: size, href: shouldHandleBackAction ? undefined : url, onClick: shouldHandleBackAction ? backActionHandler : undefined, tabIndex: tabIndex, extraProps: extraProps },
|
|
30
30
|
react_1.default.createElement(uikit_1.Icon, { data: icons_1.ArrowSidebar, size: 24 }),
|
|
31
31
|
react_1.default.createElement("span", null, title)));
|
|
32
32
|
}
|
|
@@ -3,7 +3,6 @@ import { ButtonProps as ButtonParams, QAProps } from '../../models';
|
|
|
3
3
|
export interface ButtonProps extends Omit<ButtonParams, 'url'>, QAProps {
|
|
4
4
|
className?: string;
|
|
5
5
|
url?: string;
|
|
6
|
-
urlTitle?: string;
|
|
7
6
|
onClick?: React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>;
|
|
8
7
|
}
|
|
9
8
|
declare const Button: (props: ButtonProps) => JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { MediaVideoProps } from '../../models';
|
|
3
|
+
type DefaultVideoRefType = HTMLVideoElement | undefined;
|
|
4
|
+
interface DefaultVideoProps {
|
|
5
|
+
video: MediaVideoProps;
|
|
6
|
+
qa?: string;
|
|
7
|
+
customBarControlsClassName?: string;
|
|
8
|
+
className?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare const DefaultVideo: React.ForwardRefExoticComponent<DefaultVideoProps & React.RefAttributes<DefaultVideoRefType>>;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DefaultVideo = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const react_1 = tslib_1.__importStar(require("react"));
|
|
6
|
+
const models_1 = require("../../models");
|
|
7
|
+
const utils_1 = require("../../utils");
|
|
8
|
+
const utils_2 = require("../Media/Video/utils");
|
|
9
|
+
const CustomBarControls_1 = tslib_1.__importDefault(require("../ReactPlayer/CustomBarControls"));
|
|
10
|
+
const b = (0, utils_1.block)('default-video');
|
|
11
|
+
exports.DefaultVideo = react_1.default.forwardRef((props, ref) => {
|
|
12
|
+
const { video, qa, customBarControlsClassName } = props;
|
|
13
|
+
const { controls, customControlsOptions, muted: initiallyMuted } = video;
|
|
14
|
+
const { muteButtonShown, positioning, type: customControlsType, } = customControlsOptions || {};
|
|
15
|
+
const [isPaused, setIsPaused] = (0, react_1.useState)(false);
|
|
16
|
+
const [isMuted, setIsMuted] = (0, react_1.useState)(initiallyMuted);
|
|
17
|
+
const videoRef = (0, react_1.useRef)(null);
|
|
18
|
+
// one may not use this hook and work with `ref` variable only, but
|
|
19
|
+
// in this case one should support both function type and object type,
|
|
20
|
+
// according to ForwardedRef type.
|
|
21
|
+
// Currently used way with extra ref and useImperativeHandle is more
|
|
22
|
+
// convenient and allows us to work with object typed ref only,
|
|
23
|
+
// avoiding typeof ref === 'function' statements
|
|
24
|
+
(0, react_1.useImperativeHandle)(ref, () => {
|
|
25
|
+
if (!(videoRef === null || videoRef === void 0 ? void 0 : videoRef.current)) {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
return videoRef.current;
|
|
29
|
+
}, [videoRef]);
|
|
30
|
+
const onPlayToggle = (0, react_1.useCallback)(() => {
|
|
31
|
+
setIsPaused((value) => {
|
|
32
|
+
var _a, _b;
|
|
33
|
+
if (value) {
|
|
34
|
+
(_a = videoRef === null || videoRef === void 0 ? void 0 : videoRef.current) === null || _a === void 0 ? void 0 : _a.play();
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
(_b = videoRef === null || videoRef === void 0 ? void 0 : videoRef.current) === null || _b === void 0 ? void 0 : _b.pause();
|
|
38
|
+
}
|
|
39
|
+
return !value;
|
|
40
|
+
});
|
|
41
|
+
}, [videoRef]);
|
|
42
|
+
const onMuteToggle = (0, react_1.useCallback)(() => {
|
|
43
|
+
setIsMuted((value) => !value);
|
|
44
|
+
}, []);
|
|
45
|
+
const onClick = (0, react_1.useCallback)(() => {
|
|
46
|
+
if (customControlsType === models_1.CustomControlsType.WithPlayPauseButton) {
|
|
47
|
+
onPlayToggle();
|
|
48
|
+
}
|
|
49
|
+
}, [onPlayToggle, customControlsType]);
|
|
50
|
+
return (react_1.default.createElement(react_1.Fragment, null,
|
|
51
|
+
react_1.default.createElement("video", { disablePictureInPicture: true, playsInline: true,
|
|
52
|
+
// @ts-ignore
|
|
53
|
+
// eslint-disable-next-line react/no-unknown-property
|
|
54
|
+
pip: "false", className: b(), ref: videoRef, preload: "metadata", muted: isMuted, "aria-label": video.ariaLabel, onClick: onClick }, (0, utils_2.getVideoTypesWithPriority)(video.src).map(({ src, type }, index) => (react_1.default.createElement("source", { key: index, src: src, type: type, "data-qa": qa })))),
|
|
55
|
+
controls === models_1.MediaVideoControlsType.Custom && (react_1.default.createElement(CustomBarControls_1.default, { className: customBarControlsClassName, type: customControlsType, isPaused: isPaused, onPlayClick: onPlayToggle, muteButtonShown: muteButtonShown, shown: true, positioning: positioning, mute: {
|
|
56
|
+
isMuted: Boolean(isMuted),
|
|
57
|
+
changeMute: onMuteToggle,
|
|
58
|
+
} }))));
|
|
59
|
+
});
|
|
60
|
+
exports.DefaultVideo.displayName = 'DefaultVideo';
|
|
@@ -41,13 +41,13 @@ const LabelSizeMap = {
|
|
|
41
41
|
};
|
|
42
42
|
const FileLink = (props) => {
|
|
43
43
|
const { hostname } = (0, react_1.useContext)(locationContext_1.LocationContext);
|
|
44
|
-
const { href, text, type = 'vertical', textSize = 'm', className, theme = 'default', onClick, tabIndex, urlTitle, } = props;
|
|
44
|
+
const { href, text, type = 'vertical', textSize = 'm', className, theme = 'default', onClick, tabIndex, urlTitle, extraProps, } = props;
|
|
45
45
|
const fileExt = getFileExt(href);
|
|
46
46
|
const labelTheme = (FileExtensionThemes[fileExt] || 'unknown');
|
|
47
47
|
const labelSize = LabelSizeMap[textSize];
|
|
48
48
|
return (react_1.default.createElement("div", { className: b({ ext: fileExt, type, size: textSize, theme }, className) },
|
|
49
49
|
react_1.default.createElement(uikit_1.Label, { className: b('file-label'), size: labelSize, theme: labelTheme }, fileExt),
|
|
50
50
|
react_1.default.createElement("div", { className: b('link') },
|
|
51
|
-
react_1.default.createElement("a", Object.assign({ href: href, onClick: onClick, tabIndex: tabIndex, title: urlTitle }, (0, utils_1.getLinkProps)(href, hostname)), text))));
|
|
51
|
+
react_1.default.createElement("a", Object.assign({ href: href, onClick: onClick, tabIndex: tabIndex, title: urlTitle }, (0, utils_1.getLinkProps)(href, hostname), extraProps), text))));
|
|
52
52
|
};
|
|
53
53
|
exports.default = FileLink;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { CSSProperties } from 'react';
|
|
1
|
+
import { CSSProperties, HTMLProps } from 'react';
|
|
2
2
|
import { ImageProps } from '../Image/Image';
|
|
3
3
|
export interface FullscreenImageProps extends ImageProps {
|
|
4
4
|
imageClassName?: string;
|
|
5
5
|
modalImageClass?: string;
|
|
6
6
|
imageStyle?: CSSProperties;
|
|
7
|
+
extraProps?: HTMLProps<HTMLDivElement>;
|
|
7
8
|
}
|
|
8
9
|
declare const FullscreenImage: (props: FullscreenImageProps) => JSX.Element;
|
|
9
10
|
export default FullscreenImage;
|
|
@@ -11,11 +11,11 @@ const b = (0, utils_1.block)('fullscreen-image');
|
|
|
11
11
|
const FULL_SCREEN_ICON_SIZE = 18;
|
|
12
12
|
const CLOSE_ICON_SIZE = 30;
|
|
13
13
|
const FullscreenImage = (props) => {
|
|
14
|
-
const { imageClassName, modalImageClass, imageStyle, alt = (0, i18n_1.default)('img-alt') } = props;
|
|
14
|
+
const { imageClassName, modalImageClass, imageStyle, alt = (0, i18n_1.default)('img-alt'), extraProps } = props;
|
|
15
15
|
const [isOpened, setIsOpened] = (0, react_1.useState)(false);
|
|
16
16
|
const openModal = () => setIsOpened(true);
|
|
17
17
|
const closeModal = () => setIsOpened(false);
|
|
18
|
-
return (react_1.default.createElement("div", { className: b() },
|
|
18
|
+
return (react_1.default.createElement("div", Object.assign({ className: b() }, extraProps),
|
|
19
19
|
react_1.default.createElement("div", { className: b('image-wrapper') },
|
|
20
20
|
react_1.default.createElement(Image_1.default, Object.assign({}, props, { alt: alt, className: b('image', imageClassName), onClick: openModal, style: imageStyle })),
|
|
21
21
|
react_1.default.createElement("button", { className: b('icon-wrapper'), onClick: openModal },
|
|
@@ -15,7 +15,7 @@ const DeviceSpecificFragment = ({ disableWebp, src, breakpoint, qa, }) => (react
|
|
|
15
15
|
react_1.default.createElement("source", { srcSet: src, media: `(max-width: ${breakpoint}px)`, "data-qa": qa })));
|
|
16
16
|
const Image = (props) => {
|
|
17
17
|
const projectSettings = (0, react_1.useContext)(projectSettingsContext_1.ProjectSettingsContext);
|
|
18
|
-
const { src: imageSrc, alt, disableCompress, tablet, desktop, mobile, style, className, onClick, containerClassName, qa
|
|
18
|
+
const { src: imageSrc, alt, disableCompress, tablet, desktop, mobile, style, className, onClick, containerClassName, qa } = props, rest = tslib_1.__rest(props, ["src", "alt", "disableCompress", "tablet", "desktop", "mobile", "style", "className", "onClick", "containerClassName", "qa"]);
|
|
19
19
|
const [imgLoadingError, setImgLoadingError] = (0, react_1.useState)(false);
|
|
20
20
|
const src = imageSrc || desktop;
|
|
21
21
|
if (!src) {
|
|
@@ -30,6 +30,6 @@ const Image = (props) => {
|
|
|
30
30
|
mobile && (react_1.default.createElement(DeviceSpecificFragment, { src: mobile, disableWebp: disableWebp, breakpoint: constants_1.BREAKPOINTS.sm, qa: qaAttributes.mobileSource })),
|
|
31
31
|
tablet && (react_1.default.createElement(DeviceSpecificFragment, { src: tablet, disableWebp: disableWebp, breakpoint: constants_1.BREAKPOINTS.md, qa: qaAttributes.tabletSource })),
|
|
32
32
|
src && !disableWebp && (react_1.default.createElement("source", { srcSet: checkWebP(src), type: "image/webp", "data-qa": qaAttributes.desktopSourceCompressed })),
|
|
33
|
-
react_1.default.createElement(ImageBase_1.default, { className: className, alt: alt, src: src, style: style, onClick: onClick, onError: () => setImgLoadingError(true) })));
|
|
33
|
+
react_1.default.createElement(ImageBase_1.default, Object.assign({ className: className, alt: alt, src: src, style: style, onClick: onClick, onError: () => setImgLoadingError(true) }, rest))));
|
|
34
34
|
};
|
|
35
35
|
exports.default = Image;
|
|
@@ -28,7 +28,7 @@ function getArrowSize(size) {
|
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
const LinkBlock = (props) => {
|
|
31
|
-
const { text, url, arrow, metrikaGoals, pixelEvents, analyticsEvents, theme = 'file-link', colorTheme = 'light', textSize = 'm', className, target, children, tabIndex, qa, urlTitle, } = props;
|
|
31
|
+
const { text, url, arrow, metrikaGoals, pixelEvents, analyticsEvents, theme = 'file-link', colorTheme = 'light', textSize = 'm', className, target, children, tabIndex, qa, urlTitle, extraProps, } = props;
|
|
32
32
|
const qaAttributes = (0, index_1.getQaAttrubutes)(qa, ['normal']);
|
|
33
33
|
const handleMetrika = (0, useMetrika_1.useMetrika)();
|
|
34
34
|
const handleAnalytics = (0, hooks_1.useAnalytics)(models_1.DefaultEventNames.Link, url);
|
|
@@ -43,14 +43,14 @@ const LinkBlock = (props) => {
|
|
|
43
43
|
const getLinkByType = () => {
|
|
44
44
|
switch (theme) {
|
|
45
45
|
case 'back':
|
|
46
|
-
return (react_1.default.createElement(BackLink_1.default, { title: children || text, url: href, onClick: onClick, tabIndex: tabIndex }));
|
|
46
|
+
return (react_1.default.createElement(BackLink_1.default, { title: children || text, url: href, onClick: onClick, tabIndex: tabIndex, extraProps: extraProps }));
|
|
47
47
|
case 'file-link':
|
|
48
48
|
case 'underline':
|
|
49
|
-
return (react_1.default.createElement(FileLink_1.default, { text: children || text, href: href, type: "horizontal", textSize: textSize, onClick: onClick, tabIndex: tabIndex }));
|
|
49
|
+
return (react_1.default.createElement(FileLink_1.default, { text: children || text, href: href, type: "horizontal", textSize: textSize, onClick: onClick, tabIndex: tabIndex, extraProps: extraProps }));
|
|
50
50
|
case 'normal': {
|
|
51
51
|
const linkProps = (0, utils_1.getLinkProps)(url, hostname, target);
|
|
52
52
|
const content = children || text;
|
|
53
|
-
return (react_1.default.createElement("a", Object.assign({ className: b('link', { theme: colorTheme, 'has-arrow': arrow }), href: href, onClick: onClick, tabIndex: tabIndex, title: urlTitle }, linkProps, { "data-qa": qaAttributes.normal }), arrow ? (react_1.default.createElement(react_1.Fragment, null,
|
|
53
|
+
return (react_1.default.createElement("a", Object.assign({ className: b('link', { theme: colorTheme, 'has-arrow': arrow }), href: href, onClick: onClick, tabIndex: tabIndex, title: urlTitle }, linkProps, { "data-qa": qaAttributes.normal }, extraProps), arrow ? (react_1.default.createElement(react_1.Fragment, null,
|
|
54
54
|
react_1.default.createElement("span", { className: b('content') }, content),
|
|
55
55
|
WORD_JOINER_SYM,
|
|
56
56
|
react_1.default.createElement(uikit_1.Icon, { className: b('arrow'), data: icons_1.Chevron, size: getArrowSize(textSize) }))) : (content)));
|
|
@@ -4,11 +4,6 @@ unpredictable css rules order in build */
|
|
|
4
4
|
position: relative;
|
|
5
5
|
overflow: hidden;
|
|
6
6
|
}
|
|
7
|
-
.pc-media-component-video__item {
|
|
8
|
-
width: 100%;
|
|
9
|
-
display: flex;
|
|
10
|
-
align-items: center;
|
|
11
|
-
}
|
|
12
7
|
.pc-media-component-video__react-player {
|
|
13
8
|
display: flex;
|
|
14
9
|
position: relative;
|
|
@@ -4,8 +4,8 @@ const tslib_1 = require("tslib");
|
|
|
4
4
|
const react_1 = tslib_1.__importStar(require("react"));
|
|
5
5
|
const models_1 = require("../../../models");
|
|
6
6
|
const utils_1 = require("../../../utils");
|
|
7
|
+
const DefaultVideo_1 = require("../../DefaultVideo/DefaultVideo");
|
|
7
8
|
const ReactPlayer_1 = tslib_1.__importDefault(require("../../ReactPlayer/ReactPlayer"));
|
|
8
|
-
const utils_2 = require("./utils");
|
|
9
9
|
const b = (0, utils_1.block)('media-component-video');
|
|
10
10
|
const Video = (props) => {
|
|
11
11
|
const { video, height, metrika, analyticsEvents, previewImg, playButton: commonPlayButton, customBarControlsClassName, videoClassName, playVideo, setHasVideoFallback, hasVideoFallback, qa, ratio, } = props;
|
|
@@ -47,13 +47,9 @@ const Video = (props) => {
|
|
|
47
47
|
]);
|
|
48
48
|
const defaultVideoBlock = (0, react_1.useMemo)(() => {
|
|
49
49
|
return video.src.length && !hasVideoFallback ? (react_1.default.createElement("div", { className: b('wrap', videoClassName), style: { height }, "data-qa": qaAttributes.default },
|
|
50
|
-
react_1.default.createElement(
|
|
51
|
-
// @ts-ignore
|
|
52
|
-
// eslint-disable-next-line react/no-unknown-property
|
|
53
|
-
pip: "false", className: b('item'), ref: ref, preload: "metadata", muted: true, "aria-label": video.ariaLabel }, (0, utils_2.getVideoTypesWithPriority)(video.src).map(({ src, type }, index) => (react_1.default.createElement("source", { key: index, src: src, type: type, "data-qa": qaAttributes.source })))))) : null;
|
|
50
|
+
react_1.default.createElement(DefaultVideo_1.DefaultVideo, { ref: ref, video: video, qa: qaAttributes.source }))) : null;
|
|
54
51
|
}, [
|
|
55
|
-
video
|
|
56
|
-
video.ariaLabel,
|
|
52
|
+
video,
|
|
57
53
|
hasVideoFallback,
|
|
58
54
|
videoClassName,
|
|
59
55
|
height,
|
|
@@ -2,6 +2,7 @@ import { GridColumnSizesType } from '../../grid';
|
|
|
2
2
|
import { ClassNameProps, TitleProps as TitleParams } from '../../models';
|
|
3
3
|
export interface TitleProps extends TitleParams {
|
|
4
4
|
colSizes?: GridColumnSizesType;
|
|
5
|
+
id?: string;
|
|
5
6
|
}
|
|
6
|
-
declare const Title: ({ title, subtitle, className, colSizes, }: TitleProps & ClassNameProps) => JSX.Element | null;
|
|
7
|
+
declare const Title: ({ title, subtitle, className, colSizes, id, }: TitleProps & ClassNameProps) => JSX.Element | null;
|
|
7
8
|
export default Title;
|
|
@@ -7,12 +7,12 @@ const utils_1 = require("../../utils");
|
|
|
7
7
|
const YFMWrapper_1 = tslib_1.__importDefault(require("../YFMWrapper/YFMWrapper"));
|
|
8
8
|
const TitleItem_1 = tslib_1.__importDefault(require("./TitleItem"));
|
|
9
9
|
const b = (0, utils_1.block)('title');
|
|
10
|
-
const Title = ({ title, subtitle, className, colSizes = { all: 12, sm: 8 }, }) => {
|
|
10
|
+
const Title = ({ title, subtitle, className, colSizes = { all: 12, sm: 8 }, id, }) => {
|
|
11
11
|
if (!title && !subtitle) {
|
|
12
12
|
return null;
|
|
13
13
|
}
|
|
14
14
|
const _a = !title || typeof title === 'string' ? { text: title } : title, { text } = _a, titleProps = tslib_1.__rest(_a, ["text"]);
|
|
15
|
-
return (react_1.default.createElement("div", { className: b(null, className) },
|
|
15
|
+
return (react_1.default.createElement("div", { className: b(null, className), id: id },
|
|
16
16
|
text && (react_1.default.createElement(grid_1.Col, { reset: true, sizes: colSizes },
|
|
17
17
|
react_1.default.createElement(TitleItem_1.default, Object.assign({ text: text }, titleProps)))),
|
|
18
18
|
subtitle && (react_1.default.createElement(grid_1.Col, { reset: true, sizes: colSizes },
|
|
@@ -50,13 +50,13 @@ unpredictable css rules order in build */
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
.pc-title-item__arrow {
|
|
53
|
-
margin-top:
|
|
53
|
+
margin-top: 9px;
|
|
54
54
|
}
|
|
55
55
|
.pc-title-item__arrow_size_xs {
|
|
56
|
-
margin-top:
|
|
56
|
+
margin-top: 6px;
|
|
57
57
|
}
|
|
58
58
|
.pc-title-item__arrow_size_s {
|
|
59
|
-
margin-top:
|
|
59
|
+
margin-top: 4px;
|
|
60
60
|
}
|
|
61
61
|
.pc-title-item__link {
|
|
62
62
|
color: inherit;
|
|
@@ -274,7 +274,9 @@ export interface ContentItemProps {
|
|
|
274
274
|
}
|
|
275
275
|
export interface ContentBlockProps {
|
|
276
276
|
title?: TitleItemBaseProps | string;
|
|
277
|
+
titleId?: string;
|
|
277
278
|
text?: string;
|
|
279
|
+
textId?: string;
|
|
278
280
|
additionalInfo?: string;
|
|
279
281
|
links?: LinkProps[];
|
|
280
282
|
buttons?: ButtonProps[];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { CSSProperties, ReactNode } from 'react';
|
|
1
|
+
import React, { CSSProperties, HTMLProps, ReactNode } from 'react';
|
|
2
2
|
import { ButtonView, ButtonProps as UikitButtonProps } from '@gravity-ui/uikit';
|
|
3
3
|
import { ThemeSupporting } from '../../utils';
|
|
4
4
|
import { AnalyticsEventsBase, ClassNameProps, PixelEventType, QAProps } from '../common';
|
|
@@ -95,7 +95,7 @@ interface LoopProps {
|
|
|
95
95
|
start: number;
|
|
96
96
|
end?: number;
|
|
97
97
|
}
|
|
98
|
-
export interface ImageInfoProps {
|
|
98
|
+
export interface ImageInfoProps extends Pick<HTMLProps<HTMLImageElement>, 'aria-describedby'> {
|
|
99
99
|
alt?: string;
|
|
100
100
|
disableCompress?: boolean;
|
|
101
101
|
}
|
|
@@ -138,6 +138,7 @@ export interface LinkProps extends AnalyticsEventsBase, Stylable, Tabbable {
|
|
|
138
138
|
target?: string;
|
|
139
139
|
metrikaGoals?: MetrikaGoal;
|
|
140
140
|
pixelEvents?: ButtonPixel;
|
|
141
|
+
extraProps?: HTMLProps<HTMLAnchorElement>;
|
|
141
142
|
}
|
|
142
143
|
export interface FileLinkProps extends ClassNameProps, Tabbable {
|
|
143
144
|
href: string;
|
|
@@ -147,11 +148,13 @@ export interface FileLinkProps extends ClassNameProps, Tabbable {
|
|
|
147
148
|
theme?: ContentTheme;
|
|
148
149
|
urlTitle?: string;
|
|
149
150
|
onClick?: () => void;
|
|
151
|
+
extraProps?: HTMLProps<HTMLAnchorElement>;
|
|
150
152
|
}
|
|
151
153
|
export type ButtonTheme = ButtonView | 'github' | 'app-store' | 'google-play' | 'scale' | 'monochrome';
|
|
152
154
|
export interface ButtonProps extends AnalyticsEventsBase, Pick<UikitButtonProps, 'size' | 'width' | 'extraProps'> {
|
|
153
155
|
text: string;
|
|
154
156
|
url: string;
|
|
157
|
+
urlTitle?: string;
|
|
155
158
|
primary?: boolean;
|
|
156
159
|
theme?: ButtonTheme;
|
|
157
160
|
img?: ButtonImageProps | string;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
const react_1 = tslib_1.__importDefault(require("react"));
|
|
5
|
+
const uikit_1 = require("@gravity-ui/uikit");
|
|
5
6
|
const __1 = require("../");
|
|
6
7
|
const CardBase_1 = tslib_1.__importDefault(require("../../components/CardBase/CardBase"));
|
|
7
8
|
const Image_1 = tslib_1.__importDefault(require("../../components/Image/Image"));
|
|
@@ -12,10 +13,12 @@ const b = (0, utils_2.block)('basic-card');
|
|
|
12
13
|
const BasicCard = (props) => {
|
|
13
14
|
const { title, text, icon, additionalInfo, links, buttons, iconPosition = sub_blocks_1.IconPosition.Top } = props, cardParams = tslib_1.__rest(props, ["title", "text", "icon", "additionalInfo", "links", "buttons", "iconPosition"]);
|
|
14
15
|
const iconProps = icon && (0, utils_1.getMediaImage)(icon);
|
|
15
|
-
|
|
16
|
+
const titleId = (0, uikit_1.useUniqId)();
|
|
17
|
+
const descriptionId = (0, uikit_1.useUniqId)();
|
|
18
|
+
return (react_1.default.createElement(CardBase_1.default, Object.assign({ className: b() }, cardParams, { extraProps: { 'aria-describedby': descriptionId, 'aria-labelledby': titleId } }),
|
|
16
19
|
react_1.default.createElement(CardBase_1.default.Content, null,
|
|
17
20
|
react_1.default.createElement("div", { className: b('content', { ['icon-position']: iconPosition }) },
|
|
18
21
|
iconProps && (react_1.default.createElement(Image_1.default, Object.assign({}, iconProps, { className: b('icon', { ['icon-position']: iconPosition }) }))),
|
|
19
|
-
react_1.default.createElement(__1.Content, { title: title, text: text, additionalInfo: additionalInfo, links: links, buttons: buttons, colSizes: { all: 12, md: 12 }, size: "s", className: b({ ['content-layout']: iconPosition }) })))));
|
|
22
|
+
react_1.default.createElement(__1.Content, { title: title, titleId: titleId, text: text, textId: descriptionId, additionalInfo: additionalInfo, links: links, buttons: buttons, colSizes: { all: 12, md: 12 }, size: "s", className: b({ ['content-layout']: iconPosition }) })))));
|
|
20
23
|
};
|
|
21
24
|
exports.default = BasicCard;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
const react_1 = tslib_1.__importDefault(require("react"));
|
|
5
|
+
const uikit_1 = require("@gravity-ui/uikit");
|
|
5
6
|
const components_1 = require("../../components");
|
|
6
7
|
const Link_1 = tslib_1.__importDefault(require("../../components/Link/Link"));
|
|
7
8
|
const grid_1 = require("../../grid");
|
|
@@ -37,16 +38,18 @@ function getButtonSize(size) {
|
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
const Content = (props) => {
|
|
40
|
-
const { title, text, additionalInfo, size = 'l', links, buttons, colSizes = { all: 12, sm: 8 }, centered, theme, className, list, qa, } = props;
|
|
41
|
+
const { title, titleId: titleIdFromProps, text, textId, additionalInfo, size = 'l', links, buttons, colSizes = { all: 12, sm: 8 }, centered, theme, className, list, qa, } = props;
|
|
41
42
|
const qaAttributes = (0, blocks_1.getQaAttrubutes)(qa, ['links', 'link', 'buttons', 'button', 'list']);
|
|
42
43
|
const titleProps = !title || typeof title === 'string'
|
|
43
44
|
? { text: title, textSize: getTextSize(size) }
|
|
44
45
|
: title;
|
|
45
46
|
const hasTitle = Boolean(title);
|
|
47
|
+
const defaultTitleId = (0, uikit_1.useUniqId)();
|
|
48
|
+
const titleId = titleIdFromProps || defaultTitleId;
|
|
46
49
|
return (react_1.default.createElement(grid_1.Col, { className: b({ size, centered, theme }, className), reset: true, sizes: colSizes, qa: qaAttributes.container },
|
|
47
|
-
title && react_1.default.createElement(components_1.Title, { className: b('title'), title: titleProps, colSizes: { all: 12 } }),
|
|
50
|
+
title && (react_1.default.createElement(components_1.Title, { className: b('title'), title: titleProps, colSizes: { all: 12 }, id: titleId })),
|
|
48
51
|
text && (react_1.default.createElement("div", { className: b('text', { ['without-title']: !hasTitle }) },
|
|
49
|
-
react_1.default.createElement(components_1.YFMWrapper, { content: text, modifiers: { constructor: true, [`constructor-size-${size}`]: true } }))),
|
|
52
|
+
react_1.default.createElement(components_1.YFMWrapper, { content: text, modifiers: { constructor: true, [`constructor-size-${size}`]: true }, id: textId }))),
|
|
50
53
|
(list === null || list === void 0 ? void 0 : list.length) ? react_1.default.createElement(ContentList_1.default, { list: list, size: size, qa: qaAttributes.list }) : null,
|
|
51
54
|
additionalInfo && (react_1.default.createElement("div", { className: b('notice') },
|
|
52
55
|
react_1.default.createElement(components_1.YFMWrapper, { content: additionalInfo, modifiers: {
|
|
@@ -54,7 +57,11 @@ const Content = (props) => {
|
|
|
54
57
|
'constructor-notice': true,
|
|
55
58
|
[`constructor-size-${size}`]: true,
|
|
56
59
|
} }))),
|
|
57
|
-
links && (react_1.default.createElement("div", { className: b('links'), "data-qa": qaAttributes.links }, links.map((link) => (react_1.default.createElement(Link_1.default, Object.assign({ className: b('link') }, link, { textSize: getLinkSize(size), key: link.url, qa: qaAttributes.link
|
|
58
|
-
|
|
60
|
+
links && (react_1.default.createElement("div", { className: b('links'), "data-qa": qaAttributes.links }, links.map((link) => (react_1.default.createElement(Link_1.default, Object.assign({ className: b('link') }, link, { textSize: getLinkSize(size), key: link.url, qa: qaAttributes.link, extraProps: {
|
|
61
|
+
'aria-describedby': link.urlTitle ? undefined : titleId,
|
|
62
|
+
} })))))),
|
|
63
|
+
buttons && (react_1.default.createElement("div", { className: b('buttons'), "data-qa": qaAttributes.buttons }, buttons.map((item) => (react_1.default.createElement(components_1.Button, Object.assign({ className: b('button') }, item, { key: item.url, size: getButtonSize(size), qa: qaAttributes.button, extraProps: {
|
|
64
|
+
'aria-describedby': item.urlTitle ? undefined : titleId,
|
|
65
|
+
} }))))))));
|
|
59
66
|
};
|
|
60
67
|
exports.default = Content;
|
|
@@ -239,16 +239,6 @@ unpredictable css rules order in build */
|
|
|
239
239
|
font-weight: var(--g-text-body-font-weight);
|
|
240
240
|
margin: 20px 0;
|
|
241
241
|
}
|
|
242
|
-
.pc-hubspot-form .hs-richtext a:focus {
|
|
243
|
-
box-shadow: 0 0 0 2px var(--g-color-line-focus);
|
|
244
|
-
}
|
|
245
|
-
.pc-hubspot-form .hs-richtext a:focus:not(:focus-visible) {
|
|
246
|
-
box-shadow: none;
|
|
247
|
-
}
|
|
248
|
-
.pc-hubspot-form .hs-richtext a:focus {
|
|
249
|
-
outline: 0;
|
|
250
|
-
border-radius: var(--g-focus-border-radius);
|
|
251
|
-
}
|
|
252
242
|
.pc-hubspot-form .hs_error_rollup {
|
|
253
243
|
padding-left: 10px;
|
|
254
244
|
font-size: var(--g-text-body-1-font-size);
|
|
@@ -390,6 +380,16 @@ unpredictable css rules order in build */
|
|
|
390
380
|
.pc-hubspot-form_mobile .hs-button.primary {
|
|
391
381
|
width: 80%;
|
|
392
382
|
}
|
|
383
|
+
.pc-hubspot-form a:focus {
|
|
384
|
+
box-shadow: 0 0 0 2px var(--g-color-line-focus);
|
|
385
|
+
}
|
|
386
|
+
.pc-hubspot-form a:focus:not(:focus-visible) {
|
|
387
|
+
box-shadow: none;
|
|
388
|
+
}
|
|
389
|
+
.pc-hubspot-form a:focus {
|
|
390
|
+
outline: 0;
|
|
391
|
+
border-radius: var(--g-focus-border-radius);
|
|
392
|
+
}
|
|
393
393
|
.pc-hubspot-form_theme_dark {
|
|
394
394
|
--g-color-line-focus: var(--pc-color-line-focus-dark);
|
|
395
395
|
}
|
|
@@ -10,6 +10,7 @@ export declare const getLayoutItemLinks: (links: LayoutItemProps['content']['lin
|
|
|
10
10
|
target?: string | undefined;
|
|
11
11
|
metrikaGoals?: import("../../models").MetrikaGoal | undefined;
|
|
12
12
|
pixelEvents?: import("../../models").ButtonPixel | undefined;
|
|
13
|
+
extraProps?: import("react").HTMLProps<HTMLAnchorElement> | undefined;
|
|
13
14
|
analyticsEvents?: {
|
|
14
15
|
name: string;
|
|
15
16
|
type?: string | undefined;
|
|
@@ -62,7 +62,6 @@ unpredictable css rules order in build */
|
|
|
62
62
|
}
|
|
63
63
|
.pc-quote__content_quote-type_chevron::before {
|
|
64
64
|
position: absolute;
|
|
65
|
-
top: -1px;
|
|
66
65
|
left: -10px;
|
|
67
66
|
content: "«";
|
|
68
67
|
}
|
|
@@ -71,7 +70,6 @@ unpredictable css rules order in build */
|
|
|
71
70
|
}
|
|
72
71
|
.pc-quote__content_quote-type_english-double::before {
|
|
73
72
|
position: absolute;
|
|
74
|
-
top: -1px;
|
|
75
73
|
left: -8px;
|
|
76
74
|
content: "“";
|
|
77
75
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, { useContext } from 'react';
|
|
2
|
+
import { useUniqId } from '@gravity-ui/uikit';
|
|
2
3
|
import { Button, HTML, Media, RouterLink } from '../../components';
|
|
3
4
|
import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs/HeaderBreadcrumbs';
|
|
4
5
|
import { getMediaImage } from '../../components/Media/Image/utils';
|
|
@@ -32,6 +33,7 @@ export const HeaderBlock = (props) => {
|
|
|
32
33
|
const imageThemed = image && getThemedValue(image, theme);
|
|
33
34
|
const videoThemed = video && getThemedValue(video, theme);
|
|
34
35
|
const fullWidth = (backgroundThemed === null || backgroundThemed === void 0 ? void 0 : backgroundThemed.fullWidth) || (backgroundThemed === null || backgroundThemed === void 0 ? void 0 : backgroundThemed.fullWidthMedia);
|
|
36
|
+
const titleId = useUniqId();
|
|
35
37
|
return (React.createElement("header", { className: b({
|
|
36
38
|
['has-media']: hasRightSideImage,
|
|
37
39
|
['full-width']: fullWidth,
|
|
@@ -54,7 +56,7 @@ export const HeaderBlock = (props) => {
|
|
|
54
56
|
React.createElement(Col, { sizes: titleSizes, className: b('content-inner') },
|
|
55
57
|
overtitle && (React.createElement("div", { className: b('overtitle') },
|
|
56
58
|
React.createElement(HTML, null, overtitle))),
|
|
57
|
-
React.createElement("h1", { className: b('title') },
|
|
59
|
+
React.createElement("h1", { className: b('title'), id: titleId },
|
|
58
60
|
status,
|
|
59
61
|
renderTitle ? renderTitle(title) : React.createElement(HTML, null, title)),
|
|
60
62
|
description && (React.createElement("div", { className: b('description') },
|
|
@@ -63,7 +65,9 @@ export const HeaderBlock = (props) => {
|
|
|
63
65
|
constructorTheme: textTheme,
|
|
64
66
|
} }))),
|
|
65
67
|
buttons && (React.createElement("div", { className: b('buttons'), "data-qa": "header-buttons" }, buttons.map((button, index) => (React.createElement(RouterLink, { href: button.url, key: index },
|
|
66
|
-
React.createElement(Button, Object.assign({ key: index, className: b('button'), size: "xl"
|
|
68
|
+
React.createElement(Button, Object.assign({ key: index, className: b('button'), size: "xl", extraProps: {
|
|
69
|
+
'aria-describedby': titleId,
|
|
70
|
+
} }, button))))))),
|
|
67
71
|
children))),
|
|
68
72
|
hasRightSideImage && (React.createElement(Media, { className: b('media', { [curImageSize]: true }), videoClassName: b('video'), imageClassName: b('image'), video: videoThemed, image: imageThemed })))))));
|
|
69
73
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, { Fragment, useRef, useState } from 'react';
|
|
2
|
+
import { useUniqId } from '@gravity-ui/uikit';
|
|
2
3
|
import AnimateBlock from '../../components/AnimateBlock/AnimateBlock';
|
|
3
4
|
import ButtonTabs from '../../components/ButtonTabs/ButtonTabs';
|
|
4
5
|
import FullscreenImage from '../../components/FullscreenImage/FullscreenImage';
|
|
@@ -23,10 +24,16 @@ export const TabsBlock = ({ items, title, description, animated, tabsColSizes, c
|
|
|
23
24
|
const ref = useRef(null);
|
|
24
25
|
const mediaWidth = (_a = ref === null || ref === void 0 ? void 0 : ref.current) === null || _a === void 0 ? void 0 : _a.offsetWidth;
|
|
25
26
|
const mediaHeight = mediaWidth && getHeight(mediaWidth);
|
|
27
|
+
const captionId = useUniqId();
|
|
26
28
|
let imageProps;
|
|
27
29
|
if (activeTabData) {
|
|
28
30
|
const themedImage = getThemedValue(activeTabData.image, theme);
|
|
29
31
|
imageProps = themedImage && getMediaImage(themedImage);
|
|
32
|
+
if (activeTabData.caption && imageProps) {
|
|
33
|
+
Object.assign(imageProps, {
|
|
34
|
+
'aria-describedby': captionId,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
30
37
|
}
|
|
31
38
|
const showMedia = Boolean((activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.media) || imageProps);
|
|
32
39
|
const showText = Boolean(activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.text);
|
|
@@ -45,7 +52,7 @@ export const TabsBlock = ({ items, title, description, animated, tabsColSizes, c
|
|
|
45
52
|
React.createElement("div", { ref: ref }, (activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.media) && (React.createElement(Media, Object.assign({}, getThemedValue(activeTabData.media, theme), { key: activeTab, className: b('media'), playVideo: play, height: mediaHeight })))),
|
|
46
53
|
imageProps && (React.createElement(Fragment, null,
|
|
47
54
|
React.createElement(FullscreenImage, Object.assign({}, imageProps, { imageClassName: b('image') })))),
|
|
48
|
-
(activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.caption) && React.createElement("p", { className: b('caption') }, activeTabData.caption)));
|
|
55
|
+
(activeTabData === null || activeTabData === void 0 ? void 0 : activeTabData.caption) && (React.createElement("p", { className: b('caption'), id: captionId }, activeTabData.caption))));
|
|
49
56
|
const onSelectTab = (id, e) => {
|
|
50
57
|
setActiveTab(id);
|
|
51
58
|
e.currentTarget.scrollIntoView({ inline: 'center', behavior: 'smooth', block: 'nearest' });
|