@gravity-ui/page-constructor 4.28.0-alpha.0 → 4.28.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/build/cjs/blocks/ContentLayout/ContentLayout.css +3 -0
  2. package/build/cjs/blocks/ContentLayout/ContentLayout.js +1 -1
  3. package/build/cjs/blocks/Header/Header.css +15 -0
  4. package/build/cjs/blocks/Header/Header.js +6 -2
  5. package/build/cjs/blocks/Header/schema.d.ts +8 -0
  6. package/build/cjs/blocks/Header/schema.js +4 -0
  7. package/build/cjs/blocks/HeaderSlider/schema.d.ts +4 -0
  8. package/build/cjs/blocks/Icons/Icons.css +10 -0
  9. package/build/cjs/blocks/Questions/QuestionBlockItem/QuestionBlockItem.css +15 -0
  10. package/build/cjs/blocks/Slider/Arrow/Arrow.css +7 -0
  11. package/build/cjs/blocks/Slider/Slider.js +12 -6
  12. package/build/cjs/components/Button/Button.css +6 -0
  13. package/build/cjs/components/ButtonTabs/ButtonTabs.css +3 -0
  14. package/build/cjs/components/ButtonTabs/ButtonTabs.js +1 -1
  15. package/build/cjs/components/CardBase/CardBase.d.ts +1 -2
  16. package/build/cjs/components/CardBase/CardBase.js +7 -3
  17. package/build/cjs/components/Control/Control.css +8 -0
  18. package/build/cjs/components/FileLink/FileLink.css +8 -0
  19. package/build/cjs/components/FullscreenImage/FullscreenImage.css +20 -1
  20. package/build/cjs/components/FullscreenImage/FullscreenImage.js +3 -6
  21. package/build/cjs/components/FullscreenMedia/FullscreenMedia.css +4 -0
  22. package/build/cjs/components/FullscreenMedia/FullscreenMedia.d.ts +1 -1
  23. package/build/cjs/components/FullscreenMedia/FullscreenMedia.js +4 -2
  24. package/build/cjs/components/Link/Link.css +8 -0
  25. package/build/cjs/components/Media/Image/Image.js +1 -1
  26. package/build/cjs/components/Media/Media.d.ts +1 -0
  27. package/build/cjs/components/Media/Media.js +3 -2
  28. package/build/cjs/components/Media/Video/Video.js +1 -1
  29. package/build/cjs/components/OverflowScroller/OverflowScroller.css +19 -0
  30. package/build/cjs/components/OverflowScroller/OverflowScroller.js +2 -1
  31. package/build/cjs/components/OverflowScroller/i18n/en.json +4 -0
  32. package/build/cjs/components/OverflowScroller/i18n/index.d.ts +2 -0
  33. package/build/cjs/components/OverflowScroller/i18n/index.js +8 -0
  34. package/build/cjs/components/OverflowScroller/i18n/ru.json +4 -0
  35. package/build/cjs/components/ReactPlayer/CustomBarControls.css +6 -4
  36. package/build/cjs/components/ReactPlayer/ReactPlayer.css +7 -0
  37. package/build/cjs/components/ReactPlayer/ReactPlayer.d.ts +2 -1
  38. package/build/cjs/components/ReactPlayer/ReactPlayer.js +17 -7
  39. package/build/cjs/components/Table/Table.css +1 -1
  40. package/build/cjs/components/Title/TitleItem.css +8 -0
  41. package/build/cjs/components/VideoBlock/VideoBlock.css +7 -0
  42. package/build/cjs/components/VideoBlock/VideoBlock.d.ts +1 -0
  43. package/build/cjs/components/VideoBlock/VideoBlock.js +3 -3
  44. package/build/cjs/containers/PageConstructor/PageConstructor.css +12 -1
  45. package/build/cjs/models/components.d.ts +1 -2
  46. package/build/cjs/models/constructor-items/blocks.d.ts +1 -0
  47. package/build/cjs/sub-blocks/BannerCard/BannerCard.css +3 -0
  48. package/build/cjs/sub-blocks/Content/Content.css +3 -0
  49. package/build/cjs/sub-blocks/HubspotForm/HubspotForm.css +42 -4
  50. package/build/cjs/sub-blocks/PriceDetailed/PriceDescription/PriceDescription.css +1 -1
  51. package/build/cjs/sub-blocks/PriceDetailed/PriceDetails/PriceDetails.css +20 -2
  52. package/build/cjs/sub-blocks/PriceDetailed/PriceDetails/PriceDetails.js +1 -1
  53. package/build/esm/blocks/ContentLayout/ContentLayout.css +3 -0
  54. package/build/esm/blocks/ContentLayout/ContentLayout.js +1 -1
  55. package/build/esm/blocks/Header/Header.css +15 -0
  56. package/build/esm/blocks/Header/Header.js +6 -2
  57. package/build/esm/blocks/Header/schema.d.ts +8 -0
  58. package/build/esm/blocks/Header/schema.js +4 -0
  59. package/build/esm/blocks/HeaderSlider/schema.d.ts +4 -0
  60. package/build/esm/blocks/Icons/Icons.css +10 -0
  61. package/build/esm/blocks/Questions/QuestionBlockItem/QuestionBlockItem.css +15 -0
  62. package/build/esm/blocks/Slider/Arrow/Arrow.css +7 -0
  63. package/build/esm/blocks/Slider/Slider.js +12 -6
  64. package/build/esm/components/Button/Button.css +6 -0
  65. package/build/esm/components/ButtonTabs/ButtonTabs.css +3 -0
  66. package/build/esm/components/ButtonTabs/ButtonTabs.js +1 -1
  67. package/build/esm/components/CardBase/CardBase.d.ts +1 -2
  68. package/build/esm/components/CardBase/CardBase.js +6 -2
  69. package/build/esm/components/Control/Control.css +8 -0
  70. package/build/esm/components/FileLink/FileLink.css +8 -0
  71. package/build/esm/components/FullscreenImage/FullscreenImage.css +20 -1
  72. package/build/esm/components/FullscreenImage/FullscreenImage.js +3 -6
  73. package/build/esm/components/FullscreenMedia/FullscreenMedia.css +4 -0
  74. package/build/esm/components/FullscreenMedia/FullscreenMedia.d.ts +1 -1
  75. package/build/esm/components/FullscreenMedia/FullscreenMedia.js +5 -3
  76. package/build/esm/components/Link/Link.css +8 -0
  77. package/build/esm/components/Media/Image/Image.js +2 -2
  78. package/build/esm/components/Media/Media.d.ts +1 -0
  79. package/build/esm/components/Media/Media.js +3 -2
  80. package/build/esm/components/Media/Video/Video.js +1 -1
  81. package/build/esm/components/OverflowScroller/OverflowScroller.css +19 -0
  82. package/build/esm/components/OverflowScroller/OverflowScroller.js +2 -1
  83. package/build/esm/components/OverflowScroller/i18n/en.json +4 -0
  84. package/build/esm/components/OverflowScroller/i18n/index.d.ts +2 -0
  85. package/build/esm/components/OverflowScroller/i18n/index.js +5 -0
  86. package/build/esm/components/OverflowScroller/i18n/ru.json +4 -0
  87. package/build/esm/components/ReactPlayer/CustomBarControls.css +6 -4
  88. package/build/esm/components/ReactPlayer/ReactPlayer.css +7 -0
  89. package/build/esm/components/ReactPlayer/ReactPlayer.d.ts +2 -1
  90. package/build/esm/components/ReactPlayer/ReactPlayer.js +17 -7
  91. package/build/esm/components/Table/Table.css +1 -1
  92. package/build/esm/components/Title/TitleItem.css +8 -0
  93. package/build/esm/components/VideoBlock/VideoBlock.css +7 -0
  94. package/build/esm/components/VideoBlock/VideoBlock.d.ts +1 -0
  95. package/build/esm/components/VideoBlock/VideoBlock.js +3 -3
  96. package/build/esm/containers/PageConstructor/PageConstructor.css +12 -1
  97. package/build/esm/models/components.d.ts +1 -2
  98. package/build/esm/models/constructor-items/blocks.d.ts +1 -0
  99. package/build/esm/sub-blocks/BannerCard/BannerCard.css +3 -0
  100. package/build/esm/sub-blocks/Content/Content.css +3 -0
  101. package/build/esm/sub-blocks/HubspotForm/HubspotForm.css +42 -4
  102. package/build/esm/sub-blocks/PriceDetailed/PriceDescription/PriceDescription.css +1 -1
  103. package/build/esm/sub-blocks/PriceDetailed/PriceDetails/PriceDetails.css +20 -2
  104. package/build/esm/sub-blocks/PriceDetailed/PriceDetails/PriceDetails.js +1 -1
  105. package/package.json +3 -3
  106. package/server/models/components.d.ts +1 -2
  107. package/server/models/constructor-items/blocks.d.ts +1 -0
  108. package/styles/mixins.scss +20 -0
  109. package/styles/root.scss +6 -0
  110. package/styles/styles.css +8 -1
  111. package/styles/yfm.scss +3 -1
  112. package/widget/index.js +1 -1
@@ -133,12 +133,12 @@ export const SliderBlock = (props) => {
133
133
  const renderAccessibleBar = (index) => {
134
134
  return (
135
135
  // To have this key differ from keys used in renderDot function, added `-accessible-bar` part
136
- React.createElement(Fragment, { key: `${index}-accessible-bar` }, slidesCountByBreakpoint > 1 && (React.createElement("li", { className: b('accessible-bar'), "aria-current": true, "aria-label": `Slide ${currentIndex + 1} of ${barSlidesCount}`, style: {
136
+ React.createElement(Fragment, { key: `${index}-accessible-bar` }, slidesCountByBreakpoint > 0 && (React.createElement("li", { className: b('accessible-bar'), "aria-current": true, "aria-label": `Slide ${currentIndex + 1} of ${barSlidesCount}`, style: {
137
137
  left: barPosition,
138
138
  width: barWidth,
139
139
  } }))));
140
140
  };
141
- const renderDot = (index) => {
141
+ const getCurrentSlideNumber = (index) => {
142
142
  const currentIndexDiff = index - currentIndex;
143
143
  let currentSlideNumber;
144
144
  if (0 <= currentIndexDiff && currentIndexDiff < slidesToShowCount) {
@@ -150,10 +150,16 @@ export const SliderBlock = (props) => {
150
150
  else {
151
151
  currentSlideNumber = index + 1;
152
152
  }
153
- return (React.createElement("li", { key: index, className: b('dot', { active: index === currentIndex }), onClick: () => handleDotClick(index), "aria-hidden": (slidesCountByBreakpoint > 1 &&
154
- 0 <= currentIndexDiff &&
155
- currentIndexDiff < slidesToShowCount) ||
156
- undefined, "aria-label": `Slide ${currentSlideNumber} of ${barSlidesCount}` }));
153
+ return currentSlideNumber;
154
+ };
155
+ const isVisibleSlide = (index) => {
156
+ const currentIndexDiff = index - currentIndex;
157
+ return (slidesCountByBreakpoint > 0 &&
158
+ 0 <= currentIndexDiff &&
159
+ currentIndexDiff < slidesToShowCount);
160
+ };
161
+ const renderDot = (index) => {
162
+ return (React.createElement("li", { key: index, className: b('dot', { active: index === currentIndex }), onClick: () => handleDotClick(index), "aria-hidden": isVisibleSlide(index) ? true : undefined, "aria-label": `Slide ${getCurrentSlideNumber(index)} of ${barSlidesCount}` }));
157
163
  };
158
164
  const renderNavigation = () => {
159
165
  if (childrenCount <= slidesCountByBreakpoint || !dots || childrenCount === 1) {
@@ -1,5 +1,8 @@
1
1
  /* use this for style redefinitions to awoid problems with
2
2
  unpredictable css rules order in build */
3
+ .pc-button-block {
4
+ --yc-button-outline-color: var(--g-color-line-focus);
5
+ }
3
6
  .pc-button-block__content {
4
7
  display: flex;
5
8
  align-items: center;
@@ -40,6 +43,9 @@ unpredictable css rules order in build */
40
43
  color: var(--pc-monochrome-button-color);
41
44
  }
42
45
 
46
+ .pc-button-block_theme_normal-contrast:focus::before, .pc-button-block_theme_raised:focus::before {
47
+ outline-offset: 1px;
48
+ }
43
49
  .pc-button-block_size_s {
44
50
  --btn-image-margin: 10px;
45
51
  }
@@ -26,4 +26,7 @@ unpredictable css rules order in build */
26
26
  }
27
27
  .pc-button-tabs__item.pc-button-tabs__item_active:hover {
28
28
  color: var(--pc-selected-tab-item-color);
29
+ }
30
+ .pc-button-tabs__item.pc-button-tabs__item_active:focus::before {
31
+ outline-offset: 1px;
29
32
  }
@@ -18,7 +18,7 @@ const ButtonTabs = ({ className, items, activeTab, onSelectTab, tabSize = 'l', q
18
18
  return (React.createElement("div", { className: b(null, className), "data-qa": qa }, items.map(({ id, title }) => {
19
19
  const isActive = id === activeTabId;
20
20
  return (React.createElement(Button, { text: title, className: b('item', { active: isActive }), key: title, size: tabSize, onClick: handleClick(id), extraProps: {
21
- 'aria-current': isActive,
21
+ 'aria-current': isActive || undefined,
22
22
  } }));
23
23
  })));
24
24
  };
@@ -1,6 +1,5 @@
1
1
  import React, { HTMLAttributeAnchorTarget, ReactElement } from 'react';
2
- import { ButtonPixel, CardBaseProps as CardBaseParams, ImageProps, MetrikaGoal, WithChildren } from '../../models';
3
- import { AnalyticsEventsBase } from '../../models/common';
2
+ import { AnalyticsEventsBase, ButtonPixel, CardBaseProps as CardBaseParams, ImageProps, MetrikaGoal, WithChildren } from '../../models';
4
3
  import './CardBase.css';
5
4
  export interface CardBaseProps extends AnalyticsEventsBase, CardBaseParams {
6
5
  className?: string;
@@ -1,7 +1,8 @@
1
1
  import React, { Children, Fragment } from 'react';
2
+ import { Link } from '@gravity-ui/uikit';
2
3
  import { useAnalytics } from '../../hooks';
3
4
  import { useMetrika } from '../../hooks/useMetrika';
4
- import { DefaultEventNames } from '../../models/common';
5
+ import { DefaultEventNames, } from '../../models';
5
6
  import { block, getQaAttrubutes } from '../../utils';
6
7
  import BackgroundImage from '../BackgroundImage/BackgroundImage';
7
8
  import RouterLink from '../RouterLink/RouterLink';
@@ -50,7 +51,10 @@ export const Layout = (props) => {
50
51
  handleAnalytics(analyticsEvents);
51
52
  };
52
53
  return url ? (React.createElement(RouterLink, { href: url },
53
- React.createElement("a", { href: url, target: target, rel: target === '_blank' ? 'noopener noreferrer' : undefined, className: fullClassName, draggable: false, onDragStart: (e) => e.preventDefault(), onClick: onClick, title: urlTitle, "data-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: {
55
+ draggable: false,
56
+ onDragStart: (e) => e.preventDefault(),
57
+ }, qa: qa }, cardContent))) : (React.createElement("div", { className: fullClassName, "data-qa": qa }, cardContent));
54
58
  };
55
59
  Layout.Header = Header;
56
60
  Layout.Content = Content;
@@ -4,6 +4,7 @@ unpredictable css rules order in build */
4
4
  display: flex;
5
5
  justify-content: center;
6
6
  align-items: center;
7
+ border-radius: var(--g-focus-border-radius);
7
8
  transition: color 0.2s;
8
9
  display: inline-block;
9
10
  margin: 0;
@@ -25,6 +26,13 @@ unpredictable css rules order in build */
25
26
  .utilityfocus .pc-control:focus {
26
27
  outline: 2px solid #ffdb4d;
27
28
  }
29
+ .pc-control:focus {
30
+ outline: 2px solid var(--g-color-line-focus);
31
+ outline-offset: 0;
32
+ }
33
+ .pc-control:focus:not(:focus-visible) {
34
+ outline: 0;
35
+ }
28
36
  .pc-control_size_xs {
29
37
  width: 24px;
30
38
  height: 24px;
@@ -19,6 +19,14 @@ unpredictable css rules order in build */
19
19
  }
20
20
  .pc-file-link__link > a {
21
21
  color: var(--g-color-text-primary);
22
+ border-radius: var(--g-focus-border-radius);
23
+ }
24
+ .pc-file-link__link > a:focus {
25
+ outline: 2px solid var(--g-color-line-focus);
26
+ outline-offset: 0;
27
+ }
28
+ .pc-file-link__link > a:focus:not(:focus-visible) {
29
+ outline: 0;
22
30
  }
23
31
  .pc-file-link__link > a:hover {
24
32
  color: var(--g-color-text-secondary);
@@ -6,6 +6,9 @@ unpredictable css rules order in build */
6
6
  .pc-fullscreen-image__image-wrapper {
7
7
  position: relative;
8
8
  }
9
+ .pc-fullscreen-image__image-wrapper:hover .pc-fullscreen-image__icon-wrapper {
10
+ opacity: 1;
11
+ }
9
12
  .pc-fullscreen-image__modal-content {
10
13
  position: relative;
11
14
  }
@@ -19,6 +22,15 @@ unpredictable css rules order in build */
19
22
  border-radius: var(--pc-border-radius);
20
23
  }
21
24
  .pc-fullscreen-image__icon-wrapper {
25
+ display: inline-block;
26
+ margin: 0;
27
+ padding: 0;
28
+ font: inherit;
29
+ border: none;
30
+ outline: none;
31
+ color: inherit;
32
+ background: none;
33
+ cursor: pointer;
22
34
  display: flex;
23
35
  align-items: center;
24
36
  justify-content: center;
@@ -33,7 +45,14 @@ unpredictable css rules order in build */
33
45
  opacity: 0;
34
46
  transition: 0.3s;
35
47
  }
36
- .pc-fullscreen-image__icon-wrapper_visible {
48
+ .pc-fullscreen-image__icon-wrapper:focus {
49
+ outline: 2px solid var(--g-color-line-focus);
50
+ outline-offset: 0;
51
+ }
52
+ .pc-fullscreen-image__icon-wrapper:focus:not(:focus-visible) {
53
+ outline: 0;
54
+ }
55
+ .pc-fullscreen-image__icon-wrapper:focus {
37
56
  opacity: 1;
38
57
  }
39
58
  .pc-fullscreen-image__icon {
@@ -11,19 +11,16 @@ const CLOSE_ICON_SIZE = 30;
11
11
  const FullscreenImage = (props) => {
12
12
  const { imageClassName, modalImageClass, imageStyle, alt = i18n('img-alt') } = props;
13
13
  const [isOpened, setIsOpened] = useState(false);
14
- const [isMouseEnter, setIsMouseEnter] = useState(false);
15
14
  const openModal = () => setIsOpened(true);
16
15
  const closeModal = () => setIsOpened(false);
17
- const showFullscreenIcon = () => setIsMouseEnter(true);
18
- const hideFullscreenIcon = () => setIsMouseEnter(false);
19
16
  return (React.createElement("div", { className: b() },
20
- React.createElement("div", { className: b('image-wrapper'), onMouseEnter: showFullscreenIcon, onMouseLeave: hideFullscreenIcon },
17
+ React.createElement("div", { className: b('image-wrapper') },
21
18
  React.createElement(Image, Object.assign({}, props, { alt: alt, className: b('image', imageClassName), onClick: openModal, style: imageStyle })),
22
- React.createElement("div", { className: b('icon-wrapper', { visible: isMouseEnter }), onClick: openModal },
19
+ React.createElement("button", { className: b('icon-wrapper'), onClick: openModal },
23
20
  React.createElement(Icon, { data: Fullscreen, width: FULL_SCREEN_ICON_SIZE, height: FULL_SCREEN_ICON_SIZE, className: b('icon') }))),
24
21
  isOpened && (React.createElement(Modal, { open: isOpened, onClose: closeModal, className: b('modal') },
25
22
  React.createElement("div", { className: b('modal-content') },
26
- React.createElement("div", { className: b('icon-wrapper', { visible: true }), onClick: closeModal, "aria-label": i18n('close') },
23
+ React.createElement("button", { className: b('icon-wrapper', { visible: true }), onClick: closeModal, "aria-label": i18n('close') },
27
24
  React.createElement(Icon, { data: PreviewClose, width: CLOSE_ICON_SIZE, height: CLOSE_ICON_SIZE, className: b('icon', { hover: true }) })),
28
25
  React.createElement(Image, Object.assign({}, props, { className: b('modal-image', modalImageClass) })))))));
29
26
  };
@@ -50,6 +50,10 @@ unpredictable css rules order in build */
50
50
  transition: opacity 0.3s;
51
51
  pointer-events: none;
52
52
  }
53
+ .pc-full-screen-media__modal-content .pc-full-screen-media__icon-wrapper_visible, .pc-full-screen-media__modal-content .pc-full-screen-media__icon-wrapper:focus, .pc-full-screen-media__media-wrapper .pc-full-screen-media__icon-wrapper_visible, .pc-full-screen-media__media-wrapper .pc-full-screen-media__icon-wrapper:focus {
54
+ opacity: 1;
55
+ pointer-events: inherit;
56
+ }
53
57
  .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
58
  opacity: 1;
55
59
  pointer-events: inherit;
@@ -1,7 +1,7 @@
1
1
  /// <reference types="react" />
2
2
  import { MediaAllProps } from '../Media/Media';
3
3
  import './FullscreenMedia.css';
4
- export type ChildMediaRenderProps = Pick<MediaAllProps, 'fullscreen' | 'imageClassName' | 'videoClassName' | 'youtubeClassName' | 'className'>;
4
+ export type ChildMediaRenderProps = Pick<MediaAllProps, 'fullscreen' | 'imageClassName' | 'videoClassName' | 'youtubeClassName' | 'className' | 'previewImg' | 'autoplay'>;
5
5
  export interface FullscreenMediaProps {
6
6
  showFullscreenIcon?: boolean;
7
7
  children: (props?: ChildMediaRenderProps) => JSX.Element;
@@ -1,5 +1,5 @@
1
1
  import React, { useContext, useState } from 'react';
2
- import { Icon, Modal } from '@gravity-ui/uikit';
2
+ import { Button, Icon, Modal } from '@gravity-ui/uikit';
3
3
  import { MobileContext } from '../../context/mobileContext';
4
4
  import { Fullscreen, PreviewClose } from '../../icons';
5
5
  import { block } from '../../utils';
@@ -22,17 +22,19 @@ const FullscreenMedia = ({ children, showFullscreenIcon = true }) => {
22
22
  return (React.createElement("div", { className: b() },
23
23
  React.createElement("div", { className: b('media-wrapper'), onClickCapture: openModal },
24
24
  children({ className: b('inline-media') }),
25
- showFullscreenIcon && (React.createElement("div", { className: b('icon-wrapper'), onClickCapture: openModal },
25
+ showFullscreenIcon && (React.createElement(Button, { className: b('icon-wrapper'), extraProps: { onClickCapture: openModal }, size: 'l' },
26
26
  React.createElement(Icon, { data: Fullscreen, width: FULL_SCREEN_ICON_SIZE, height: FULL_SCREEN_ICON_SIZE, className: b('icon') })))),
27
27
  isOpened && (React.createElement(Modal, { open: isOpened, onClose: closeModal, className: b('modal') },
28
28
  React.createElement("div", { className: b('modal-content') },
29
- React.createElement("div", { className: b('icon-wrapper', { visible: true }), onClick: closeModal },
29
+ React.createElement(Button, { className: b('icon-wrapper', { visible: true }), onClick: closeModal, size: 'l' },
30
30
  React.createElement(Icon, { data: PreviewClose, width: CLOSE_ICON_SIZE, height: CLOSE_ICON_SIZE, className: b('icon', { hover: true }) })),
31
31
  children({
32
32
  imageClassName: getMediaClass('image'),
33
33
  videoClassName: getMediaClass('video'),
34
34
  youtubeClassName: getMediaClass('youtube'),
35
35
  fullscreen: true,
36
+ previewImg: undefined,
37
+ autoplay: true,
36
38
  }))))));
37
39
  };
38
40
  export default FullscreenMedia;
@@ -10,6 +10,7 @@ unpredictable css rules order in build */
10
10
  cursor: pointer;
11
11
  display: flex;
12
12
  align-items: center;
13
+ border-radius: var(--g-focus-border-radius);
13
14
  }
14
15
  .utilityfocus .pc-link-block__link:focus {
15
16
  outline: 2px solid #ffdb4d;
@@ -18,6 +19,13 @@ unpredictable css rules order in build */
18
19
  --pc-text-header-color: var(--g-color-text-link-hover);
19
20
  color: var(--g-color-text-link-hover);
20
21
  }
22
+ .pc-link-block__link:focus {
23
+ outline: 2px solid var(--g-color-line-focus);
24
+ outline-offset: 0;
25
+ }
26
+ .pc-link-block__link:focus:not(:focus-visible) {
27
+ outline: 0;
28
+ }
21
29
  .pc-link-block__link_theme_dark {
22
30
  color: var(--g-color-text-light-primary);
23
31
  }
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useState } from 'react';
1
+ import React, { Fragment, useEffect, useState } from 'react';
2
2
  import debounce from 'lodash/debounce';
3
3
  import { animated, config, useSpring } from 'react-spring';
4
4
  import SliderBlock from '../../../blocks/Slider/Slider';
@@ -50,7 +50,7 @@ const Image = (props) => {
50
50
  };
51
51
  const imageSlider = (imageArray) => {
52
52
  const fullscreenItem = fullscreen === undefined || fullscreen;
53
- return (React.createElement(SliderBlock, { slidesToShow: 1, type: SliderType.MediaCard }, imageArray.map((item) => fullscreenItem ? renderFullscreenImage(item) : imageOnly(item))));
53
+ return (React.createElement(SliderBlock, { slidesToShow: 1, type: SliderType.MediaCard }, imageArray.map((item, index) => (React.createElement(Fragment, { key: index }, fullscreenItem ? renderFullscreenImage(item) : imageOnly(item))))));
54
54
  };
55
55
  if (Array.isArray(image)) {
56
56
  return imageSlider(image);
@@ -5,6 +5,7 @@ import './Media.css';
5
5
  export interface MediaAllProps extends MediaProps, VideoAdditionProps, ImageAdditionProps, QAProps {
6
6
  className?: string;
7
7
  youtubeClassName?: string;
8
+ autoplay?: boolean;
8
9
  }
9
10
  export declare const Media: (props: MediaAllProps) => JSX.Element;
10
11
  export default Media;
@@ -8,7 +8,7 @@ import Video from './Video/Video';
8
8
  import './Media.css';
9
9
  const b = block('Media');
10
10
  export const Media = (props) => {
11
- const { image, video, youtube, dataLens, color, height, previewImg, parallax = false, metrika, fullscreen, analyticsEvents, className, imageClassName, videoClassName, youtubeClassName, playVideo = true, isBackground, playButton, customBarControlsClassName, qa, ratio, } = props;
11
+ const { image, video, youtube, dataLens, color, height, previewImg, parallax = false, metrika, fullscreen, analyticsEvents, className, imageClassName, videoClassName, youtubeClassName, playVideo = true, isBackground, playButton, customBarControlsClassName, qa, ratio, autoplay, } = props;
12
12
  const [hasVideoFallback, setHasVideoFallback] = useState(false);
13
13
  const qaAttributes = getQaAttrubutes(qa, 'video');
14
14
  const content = useMemo(() => {
@@ -40,7 +40,7 @@ export const Media = (props) => {
40
40
  }
41
41
  }
42
42
  if (youtube) {
43
- result = (React.createElement(YoutubeBlock, { className: b('youtube', youtubeClassName), record: youtube, attributes: { color: 'white', rel: '0' }, previewImg: previewImg, height: height, fullscreen: fullscreen, analyticsEvents: analyticsEvents }));
43
+ result = (React.createElement(YoutubeBlock, { className: b('youtube', youtubeClassName), record: youtube, attributes: { color: 'white', rel: '0' }, previewImg: previewImg, height: height, fullscreen: fullscreen, analyticsEvents: analyticsEvents, autoplay: autoplay }));
44
44
  }
45
45
  if (dataLens) {
46
46
  result = React.createElement(DataLens, { dataLens: dataLens });
@@ -68,6 +68,7 @@ export const Media = (props) => {
68
68
  customBarControlsClassName,
69
69
  ratio,
70
70
  youtubeClassName,
71
+ autoplay,
71
72
  ]);
72
73
  return (React.createElement("div", { className: b(null, className), style: { backgroundColor: color }, "data-qa": qa }, content));
73
74
  };
@@ -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,
@@ -1,3 +1,5 @@
1
+ /* use this for style redefinitions to awoid problems with
2
+ unpredictable css rules order in build */
1
3
  .pc-overflow-scroller {
2
4
  display: flex;
3
5
  align-items: center;
@@ -19,6 +21,15 @@
19
21
  transition: left 0.6s;
20
22
  }
21
23
  .pc-overflow-scroller__arrow {
24
+ display: inline-block;
25
+ margin: 0;
26
+ padding: 0;
27
+ font: inherit;
28
+ border: none;
29
+ outline: none;
30
+ color: inherit;
31
+ background: none;
32
+ cursor: pointer;
22
33
  position: absolute;
23
34
  z-index: 10;
24
35
  top: 0;
@@ -29,6 +40,14 @@
29
40
  height: calc(100% - 1px);
30
41
  cursor: pointer;
31
42
  color: var(--g-color-text-secondary);
43
+ border-radius: var(--g-focus-border-radius);
44
+ }
45
+ .pc-overflow-scroller__arrow:focus {
46
+ outline: 2px solid var(--g-color-line-focus);
47
+ outline-offset: 0;
48
+ }
49
+ .pc-overflow-scroller__arrow:focus:not(:focus-visible) {
50
+ outline: 0;
32
51
  }
33
52
  .pc-overflow-scroller__arrow_type_left {
34
53
  left: 0;
@@ -2,6 +2,7 @@ import React, { createRef } from 'react';
2
2
  import debounce from 'lodash/debounce';
3
3
  import { ToggleArrow } from '..';
4
4
  import { block } from '../../utils';
5
+ import i18n from './i18n';
5
6
  import './OverflowScroller.css';
6
7
  const b = block('overflow-scroller');
7
8
  const TRANSITION_TIME = 300;
@@ -82,7 +83,7 @@ export default class OverflowScroller extends React.Component {
82
83
  }) },
83
84
  React.createElement("div", { className: b(null, className), ref: this.containerRef },
84
85
  React.createElement("div", { className: b('wrapper'), style: wrapperStyle, ref: this.wrapperRef }, children)),
85
- arrows.map((direction) => (React.createElement("div", { key: direction, className: b('arrow', { type: direction }, arrowClassName), onClick: (e) => this.handleScrollClick(e, direction) },
86
+ arrows.map((direction) => (React.createElement("button", { key: direction, className: b('arrow', { type: direction }, arrowClassName), onClick: (e) => this.handleScrollClick(e, direction), "aria-label": i18n(direction) },
86
87
  React.createElement(ToggleArrow, { size: arrowSize, type: 'horizontal', iconType: "navigation" }))))));
87
88
  }
88
89
  }
@@ -0,0 +1,4 @@
1
+ {
2
+ "left": "Previous",
3
+ "right": "Next"
4
+ }
@@ -0,0 +1,2 @@
1
+ declare const _default: (key: string, params?: import("@gravity-ui/i18n").Params | undefined) => string;
2
+ export default _default;
@@ -0,0 +1,5 @@
1
+ import { registerKeyset } from '../../../utils/registerKeyset';
2
+ import en from './en.json';
3
+ import ru from './ru.json';
4
+ const COMPONENT = 'OverflowScroller';
5
+ export default registerKeyset({ en, ru }, COMPONENT);
@@ -0,0 +1,4 @@
1
+ {
2
+ "left": "Предыдущий",
3
+ "right": "Следующий"
4
+ }
@@ -56,10 +56,11 @@ unpredictable css rules order in build */
56
56
  background: #eff2f8;
57
57
  }
58
58
  .pc-CustomBarControls__button_type_with-mute-button:focus {
59
- outline: 2px solid var(--g-color-line-misc);
59
+ outline: 2px solid var(--g-color-line-focus);
60
+ outline-offset: 0;
60
61
  }
61
62
  .pc-CustomBarControls__button_type_with-mute-button:focus:not(:focus-visible) {
62
- outline: none;
63
+ outline: 0;
63
64
  }
64
65
  .pc-CustomBarControls__button_type_with-play-pause-button {
65
66
  width: 42px;
@@ -68,10 +69,11 @@ unpredictable css rules order in build */
68
69
  background: var(--g-color-base-background);
69
70
  }
70
71
  .pc-CustomBarControls__button_type_with-play-pause-button:focus {
71
- outline: 2px solid var(--g-color-line-misc);
72
+ outline: 2px solid var(--g-color-line-focus);
73
+ outline-offset: 0;
72
74
  }
73
75
  .pc-CustomBarControls__button_type_with-play-pause-button:focus:not(:focus-visible) {
74
- outline: none;
76
+ outline: 0;
75
77
  }
76
78
  .pc-CustomBarControls__play-icon_type_with-play-pause-button {
77
79
  height: 16px;
@@ -27,6 +27,13 @@ unpredictable css rules order in build */
27
27
  height: 64px;
28
28
  border-radius: 166px;
29
29
  }
30
+ .pc-ReactPlayer__button:focus {
31
+ outline: 2px solid var(--g-color-line-focus);
32
+ outline-offset: 0;
33
+ }
34
+ .pc-ReactPlayer__button:focus:not(:focus-visible) {
35
+ outline: 0;
36
+ }
30
37
  .pc-ReactPlayer__button_theme_blue {
31
38
  color: var(--g-color-base-background);
32
39
  background-color: var(--g-color-base-brand);
@@ -12,5 +12,6 @@ export interface ReactPlayerBlockProps extends Omit<MediaVideoProps, 'loop' | 's
12
12
  ratio?: number;
13
13
  children?: React.ReactNode;
14
14
  }
15
- export declare const ReactPlayerBlock: React.ForwardRefExoticComponent<ReactPlayerBlockProps & React.RefAttributes<ReactPlayerBlockHandler>>;
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
- pause: () => setIsPlaying(false),
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);
@@ -216,12 +226,12 @@ export const ReactPlayerBlock = React.forwardRef((props, originRef) => {
216
226
  }, className), ref: ref, onClick: handleClick, onMouseEnter: onFocusIn, onMouseLeave: onFocusOut, onFocus: onFocusIn, onBlur: onFocusOut }, isMounted ? (React.createElement(Fragment, null,
217
227
  React.createElement(ReactPlayer, { className: b('player'), url: videoSrc, muted: muted, controls: controls === MediaVideoControlsType.Default, height: currentHeight || '100%', width: width || '100%', light: previewImgUrl, playing: isPlaying, playIcon: playIcon, progressInterval: FPS, onClickPreview: handleClickPreview, onStart: onStart, onReady: setPlayerRef, onPlay: onPlay, onPause: autoPlay && customControlsType !== CustomControlsType.WithMuteButton
218
228
  ? undefined
219
- : onPause, onProgress: onProgress, onEnded: onEnded, "aria-label": ariaLabel, config: {
229
+ : onPause, onProgress: onProgress, onEnded: onEnded, "aria-label": ariaLabel, previewTabIndex: -1, config: {
220
230
  file: {
221
231
  attributes: {
222
- pip: props.autoplay ? 'false' : undefined,
223
- playsinline: props.autoplay ? '' : undefined,
224
- disablepictureinpicture: props.autoplay ? '' : undefined,
232
+ pip: isMobile ? 'false' : undefined,
233
+ playsinline: isMobile ? '' : undefined,
234
+ disablepictureinpicture: isMobile ? '' : undefined,
225
235
  },
226
236
  },
227
237
  } }),
@@ -13,7 +13,7 @@ unpredictable css rules order in build */
13
13
  display: flex;
14
14
  }
15
15
  .pc-table__row:first-child {
16
- font-weight: 500;
16
+ font-weight: var(--g-text-accent-font-weight);
17
17
  }
18
18
  .pc-table__row:first-child .pc-table__cell {
19
19
  border-bottom-color: var(--g-color-line-generic-active);
@@ -62,11 +62,19 @@ unpredictable css rules order in build */
62
62
  color: inherit;
63
63
  text-decoration: none;
64
64
  padding-right: 8px;
65
+ border-radius: var(--g-focus-border-radius);
65
66
  }
66
67
  .pc-title-item__link:hover, .pc-title-item__link:active {
67
68
  --pc-text-header-color: inherit;
68
69
  color: inherit;
69
70
  }
71
+ .pc-title-item__link:focus {
72
+ outline: 2px solid var(--g-color-line-focus);
73
+ outline-offset: 0;
74
+ }
75
+ .pc-title-item__link:focus:not(:focus-visible) {
76
+ outline: 0;
77
+ }
70
78
  .pc-title-item__link:hover {
71
79
  cursor: pointer;
72
80
  }
@@ -43,6 +43,13 @@ unpredictable css rules order in build */
43
43
  background-color: var(--g-color-base-brand);
44
44
  border-radius: 50%;
45
45
  }
46
+ .pc-VideoBlock__button:focus {
47
+ outline: 2px solid var(--g-color-line-focus);
48
+ outline-offset: 0;
49
+ }
50
+ .pc-VideoBlock__button:focus:not(:focus-visible) {
51
+ outline: 0;
52
+ }
46
53
  .pc-VideoBlock__icon {
47
54
  margin-left: 6px;
48
55
  }
@@ -16,6 +16,7 @@ export interface VideoBlockProps extends AnalyticsEventsBase {
16
16
  playButton?: React.ReactNode;
17
17
  height?: number;
18
18
  fullscreen?: boolean;
19
+ autoplay?: boolean;
19
20
  }
20
21
  declare const VideoBlock: (props: VideoBlockProps) => JSX.Element | null;
21
22
  export default VideoBlock;
@@ -37,7 +37,7 @@ export function getHeight(width) {
37
37
  return (width / 16) * 9;
38
38
  }
39
39
  const VideoBlock = (props) => {
40
- const { stream, record, attributes, className, id, previewImg, playButton, height, fullscreen, analyticsEvents, } = props;
40
+ const { stream, record, attributes, className, id, previewImg, playButton, height, fullscreen, analyticsEvents, autoplay, } = props;
41
41
  const handleAnalytics = useAnalytics(DefaultEventNames.VideoPreview);
42
42
  const src = getVideoSrc(stream, record);
43
43
  const ref = useRef(null);
@@ -71,7 +71,7 @@ const VideoBlock = (props) => {
71
71
  const iframe = document.createElement('iframe');
72
72
  iframe.id = fullId;
73
73
  if (!previewImg) {
74
- iframe.src = `${src}?${getPageSearchParams(attributes || {})}`;
74
+ iframe.src = `${src}?${getPageSearchParams(Object.assign(Object.assign({}, (attributes || {})), (autoplay ? AUTOPLAY_ATTRIBUTES : {})))}`;
75
75
  }
76
76
  iframe.width = '100%';
77
77
  iframe.height = '100%';
@@ -83,7 +83,7 @@ const VideoBlock = (props) => {
83
83
  ref.current.appendChild(iframe);
84
84
  iframeRef.current = iframe;
85
85
  }
86
- }, [stream, record, norender, src, fullId, attributes, iframeRef, previewImg]);
86
+ }, [stream, record, norender, src, fullId, attributes, iframeRef, previewImg, autoplay]);
87
87
  useEffect(() => {
88
88
  setHidePreview(false);
89
89
  }, [src, setHidePreview]);