@gravity-ui/page-constructor 5.27.0 → 5.27.1-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/README.md +54 -0
  2. package/build/cjs/blocks/HeaderSlider/HeaderSlider.css +0 -10
  3. package/build/cjs/blocks/HeaderSlider/HeaderSlider.js +2 -2
  4. package/build/cjs/blocks/Slider/Slider.css +2 -0
  5. package/build/cjs/blocks/Slider/Slider.d.ts +1 -0
  6. package/build/cjs/blocks/Slider/Slider.js +85 -31
  7. package/build/cjs/blocks/Slider/i18n/en.json +3 -1
  8. package/build/cjs/blocks/Slider/i18n/index.d.ts +1 -1
  9. package/build/cjs/blocks/Slider/i18n/ru.json +3 -1
  10. package/build/cjs/blocks/Slider/utils.d.ts +10 -0
  11. package/build/cjs/blocks/Slider/utils.js +85 -1
  12. package/build/cjs/blocks/SliderNew/Arrow/Arrow.css +23 -19
  13. package/build/cjs/blocks/SliderNew/Arrow/Arrow.d.ts +4 -1
  14. package/build/cjs/blocks/SliderNew/Arrow/Arrow.js +5 -4
  15. package/build/cjs/blocks/SliderNew/Slider.css +103 -22
  16. package/build/cjs/blocks/SliderNew/Slider.d.ts +2 -1
  17. package/build/cjs/blocks/SliderNew/Slider.js +22 -9
  18. package/build/cjs/blocks/SliderNew/i18n/en.json +3 -1
  19. package/build/cjs/blocks/SliderNew/i18n/index.d.ts +1 -1
  20. package/build/cjs/blocks/SliderNew/i18n/ru.json +3 -1
  21. package/build/cjs/blocks/SliderNew/useSlider.d.ts +8 -6
  22. package/build/cjs/blocks/SliderNew/useSlider.js +4 -2
  23. package/build/cjs/blocks/SliderNew/useSliderPagination.d.ts +9 -0
  24. package/build/cjs/blocks/SliderNew/useSliderPagination.js +36 -0
  25. package/build/cjs/blocks/SliderNew/utils.d.ts +2 -0
  26. package/build/cjs/blocks/SliderNew/utils.js +13 -1
  27. package/build/cjs/components/FullscreenImage/FullscreenImage.css +48 -8
  28. package/build/cjs/components/FullscreenImage/FullscreenImage.d.ts +5 -0
  29. package/build/cjs/components/FullscreenImage/FullscreenImage.js +17 -3
  30. package/build/cjs/components/Media/Image/Image.d.ts +1 -0
  31. package/build/cjs/components/Media/Image/Image.js +7 -5
  32. package/build/cjs/components/Media/Media.css +4 -0
  33. package/build/cjs/components/Media/Media.d.ts +1 -0
  34. package/build/cjs/components/Media/Media.js +3 -2
  35. package/build/cjs/components/MediaBase/MediaBase.js +1 -1
  36. package/build/cjs/components/ReactPlayer/ReactPlayer.js +1 -1
  37. package/build/cjs/constructor-items.d.ts +1 -1
  38. package/build/cjs/models/constructor-items/blocks.d.ts +2 -1
  39. package/build/cjs/models/constructor-items/blocks.js +1 -0
  40. package/build/cjs/navigation/hooks/useShowBorder.js +3 -2
  41. package/build/cjs/sub-blocks/Content/Content.css +14 -4
  42. package/build/cjs/sub-blocks/ImageCard/ImageCard.css +8 -0
  43. package/build/esm/blocks/HeaderSlider/HeaderSlider.css +0 -10
  44. package/build/esm/blocks/HeaderSlider/HeaderSlider.js +1 -1
  45. package/build/esm/blocks/Slider/Slider.css +2 -0
  46. package/build/esm/blocks/Slider/Slider.d.ts +1 -0
  47. package/build/esm/blocks/Slider/Slider.js +86 -32
  48. package/build/esm/blocks/Slider/i18n/en.json +3 -1
  49. package/build/esm/blocks/Slider/i18n/index.d.ts +1 -1
  50. package/build/esm/blocks/Slider/i18n/ru.json +3 -1
  51. package/build/esm/blocks/Slider/utils.d.ts +10 -0
  52. package/build/esm/blocks/Slider/utils.js +82 -0
  53. package/build/esm/blocks/SliderNew/Arrow/Arrow.css +23 -19
  54. package/build/esm/blocks/SliderNew/Arrow/Arrow.d.ts +4 -1
  55. package/build/esm/blocks/SliderNew/Arrow/Arrow.js +5 -4
  56. package/build/esm/blocks/SliderNew/Slider.css +103 -22
  57. package/build/esm/blocks/SliderNew/Slider.d.ts +2 -1
  58. package/build/esm/blocks/SliderNew/Slider.js +22 -9
  59. package/build/esm/blocks/SliderNew/i18n/en.json +3 -1
  60. package/build/esm/blocks/SliderNew/i18n/index.d.ts +1 -1
  61. package/build/esm/blocks/SliderNew/i18n/ru.json +3 -1
  62. package/build/esm/blocks/SliderNew/useSlider.d.ts +8 -6
  63. package/build/esm/blocks/SliderNew/useSlider.js +6 -3
  64. package/build/esm/blocks/SliderNew/useSliderPagination.d.ts +9 -0
  65. package/build/esm/blocks/SliderNew/useSliderPagination.js +32 -0
  66. package/build/esm/blocks/SliderNew/utils.d.ts +2 -0
  67. package/build/esm/blocks/SliderNew/utils.js +10 -0
  68. package/build/esm/components/FullscreenImage/FullscreenImage.css +48 -8
  69. package/build/esm/components/FullscreenImage/FullscreenImage.d.ts +5 -0
  70. package/build/esm/components/FullscreenImage/FullscreenImage.js +18 -4
  71. package/build/esm/components/Media/Image/Image.d.ts +1 -0
  72. package/build/esm/components/Media/Image/Image.js +7 -5
  73. package/build/esm/components/Media/Media.css +4 -0
  74. package/build/esm/components/Media/Media.d.ts +1 -0
  75. package/build/esm/components/Media/Media.js +3 -2
  76. package/build/esm/components/MediaBase/MediaBase.js +1 -1
  77. package/build/esm/components/ReactPlayer/ReactPlayer.js +1 -1
  78. package/build/esm/constructor-items.d.ts +1 -1
  79. package/build/esm/models/constructor-items/blocks.d.ts +2 -1
  80. package/build/esm/models/constructor-items/blocks.js +1 -0
  81. package/build/esm/navigation/hooks/useShowBorder.js +1 -1
  82. package/build/esm/sub-blocks/Content/Content.css +14 -4
  83. package/build/esm/sub-blocks/ImageCard/ImageCard.css +8 -0
  84. package/package.json +2 -1
  85. package/server/models/constructor-items/blocks.d.ts +2 -1
  86. package/server/models/constructor-items/blocks.js +1 -0
  87. package/styles/mixins.scss +1 -1
  88. package/widget/index.js +1 -1
@@ -27,6 +27,14 @@ unpredictable css rules order in build */
27
27
  .pc-SliderNewBlock__slide.swiper-slide.swiper-slide-visible {
28
28
  animation: safari-fix 300ms;
29
29
  }
30
+ .pc-SliderNewBlock__slide.swiper-slide .pc-SliderNewBlock__slide-item {
31
+ width: 100%;
32
+ height: 100%;
33
+ }
34
+ .pc-SliderNewBlock .pc-SliderNewBlock__slide-item {
35
+ width: 100%;
36
+ height: 100%;
37
+ }
30
38
  .pc-SliderNewBlock__arrow {
31
39
  position: absolute;
32
40
  top: -2px;
@@ -48,6 +56,7 @@ unpredictable css rules order in build */
48
56
  background-color: var(--g-color-line-generic-accent);
49
57
  cursor: pointer;
50
58
  display: inline-block;
59
+ transition: background-color 1s;
51
60
  }
52
61
  .pc-SliderNewBlock__dot:hover {
53
62
  background-color: var(--g-color-line-generic-accent-hover);
@@ -712,7 +721,7 @@ unpredictable css rules order in build */
712
721
  padding: 0;
713
722
  }
714
723
  @media (max-width: 577px) {
715
- .pc-SliderNewBlock_type_media-card:not(.pc-SliderNewBlock_type_media-card_one-slide) {
724
+ .pc-SliderNewBlock_type_media-card:not(.pc-SliderNewBlock_one-slide) {
716
725
  margin-left: 0;
717
726
  padding-left: 0;
718
727
  width: 100%;
@@ -746,14 +755,6 @@ unpredictable css rules order in build */
746
755
  .pc-SliderNewBlock_type_header-card {
747
756
  padding-top: 0;
748
757
  }
749
- @media (max-width: 577px) {
750
- .pc-SliderNewBlock_type_header-card:not(.pc-SliderNewBlock_type_header-card_one-slide) {
751
- margin-left: 0;
752
- padding-left: 0;
753
- width: 100%;
754
- overflow: inherit;
755
- }
756
- }
757
758
  .pc-SliderNewBlock_type_header-card .pc-SliderNewBlock__wrapper {
758
759
  position: relative;
759
760
  }
@@ -775,32 +776,109 @@ unpredictable css rules order in build */
775
776
  left: 0;
776
777
  margin-right: 0;
777
778
  }
778
- .pc-SliderNewBlock_type_header-card .pc-SliderNewBlock__arrow button {
779
- background-color: transparent;
780
- box-shadow: none;
779
+ .pc-SliderNewBlock_type_header-card:has(.swiper-slide-active .pc-header-block_controls-view_light) .pc-slider-new-block-arrow__inner {
780
+ color: var(--g-color-text-dark-primary);
781
+ }
782
+ .pc-SliderNewBlock_type_header-card:has(.swiper-slide-active .pc-header-block_controls-view_light) .pc-SliderNewBlock__dot {
783
+ background-color: var(--g-color-private-black-150);
784
+ }
785
+ .pc-SliderNewBlock_type_header-card:has(.swiper-slide-active .pc-header-block_controls-view_light) .pc-SliderNewBlock__dot_active {
786
+ background-color: var(--g-color-private-black-300);
787
+ }
788
+ .pc-SliderNewBlock_type_header-card:has(.swiper-slide-active .pc-header-block_controls-view_dark) .pc-slider-new-block-arrow__inner {
789
+ color: var(--g-color-text-light-primary);
781
790
  }
782
- .pc-SliderNewBlock_type_header-card .pc-SliderNewBlock__arrow button:hover {
783
- box-shadow: none;
791
+ .pc-SliderNewBlock_type_header-card:has(.swiper-slide-active .pc-header-block_controls-view_dark) .pc-SliderNewBlock__dot {
792
+ background-color: var(--g-color-private-white-150);
784
793
  }
785
- .pc-SliderNewBlock_type_header-card .pc-SliderNewBlock__arrow:hover button {
786
- box-shadow: none;
794
+ .pc-SliderNewBlock_type_header-card:has(.swiper-slide-active .pc-header-block_controls-view_dark) .pc-SliderNewBlock__dot_active {
795
+ background-color: var(--g-color-private-white-300);
787
796
  }
788
797
  .pc-SliderNewBlock_type_header-card .pc-SliderNewBlock__slide {
789
798
  padding: 0;
790
799
  }
800
+ @media (max-width: 769px) {
801
+ .pc-SliderNewBlock_type_header-card:not(.pc-SliderNewBlock_one-slide) {
802
+ margin-left: -8px;
803
+ padding-left: 0;
804
+ width: calc(100% + 8px);
805
+ }
806
+ }
791
807
  @media (max-width: 577px) {
792
808
  .pc-SliderNewBlock_type_header-card .pc-SliderNewBlock__arrow {
793
809
  display: none;
794
810
  }
795
- .pc-SliderNewBlock_type_header-card.pc-SliderNewBlock:not(.pc-SliderNewBlock_type_header-card_one-slide) .pc-SliderNewBlock__slider {
811
+ .pc-SliderNewBlock_type_header-card:not(.pc-SliderNewBlock_one-slide) .pc-SliderNewBlock__slider {
796
812
  margin-left: 0;
797
813
  }
798
- .pc-SliderNewBlock_type_header-card.pc-SliderNewBlock:not(.pc-SliderNewBlock_type_header-card_one-slide) .pc-SliderNewBlock__slide {
799
- padding-right: 0;
814
+ .pc-SliderNewBlock_type_header-card:not(.pc-SliderNewBlock_one-slide) .swiper-wrapper {
800
815
  padding-left: 0;
801
816
  }
802
- .pc-SliderNewBlock_type_header-card.pc-SliderNewBlock:not(.pc-SliderNewBlock_type_header-card_one-slide) .pc-SliderNewBlock__slide:last-child {
817
+ .pc-SliderNewBlock_type_header-card:not(.pc-SliderNewBlock_one-slide) .pc-SliderNewBlock__slide {
803
818
  padding-right: 0;
819
+ padding-left: 0;
820
+ }
821
+ }
822
+ .pc-SliderNewBlock_type_fullscreen-card {
823
+ padding-top: 0;
824
+ }
825
+ @media (max-width: 577px) {
826
+ .pc-SliderNewBlock_type_fullscreen-card:not(.pc-SliderNewBlock_one-slide) {
827
+ margin-left: 0;
828
+ padding-left: 0;
829
+ width: 100%;
830
+ overflow: inherit;
831
+ }
832
+ }
833
+ .pc-SliderNewBlock_type_fullscreen-card .pc-SliderNewBlock__slider {
834
+ padding: 24px 0 40px;
835
+ height: 100vh;
836
+ margin: 0;
837
+ }
838
+ .pc-SliderNewBlock_type_fullscreen-card .pc-SliderNewBlock__slider .swiper-pagination {
839
+ bottom: 11px;
840
+ }
841
+ .pc-SliderNewBlock_type_fullscreen-card .pc-SliderNewBlock__slider .pc-SliderNewBlock__dot {
842
+ background-color: var(--g-color-text-light-hint);
843
+ }
844
+ .pc-SliderNewBlock_type_fullscreen-card .pc-SliderNewBlock__slider .pc-SliderNewBlock__dot_active {
845
+ background-color: var(--g-color-text-light-primary);
846
+ }
847
+ .pc-SliderNewBlock_type_fullscreen-card .pc-SliderNewBlock__slider .pc-SliderNewBlock__slide {
848
+ height: 100%;
849
+ padding: 0 120px;
850
+ }
851
+ .pc-SliderNewBlock_type_fullscreen-card:hover .pc-SliderNewBlock__arrow {
852
+ display: flex;
853
+ }
854
+ .pc-SliderNewBlock_type_fullscreen-card .pc-SliderNewBlock__arrow {
855
+ display: none;
856
+ width: 120px;
857
+ top: 40px;
858
+ bottom: 40px;
859
+ }
860
+ .pc-SliderNewBlock_type_fullscreen-card .pc-SliderNewBlock__arrow_prev {
861
+ left: 0;
862
+ margin-right: 0;
863
+ }
864
+ @media (max-width: 769px) {
865
+ .pc-SliderNewBlock_type_fullscreen-card {
866
+ margin-left: 0;
867
+ }
868
+ .pc-SliderNewBlock_type_fullscreen-card .pc-SliderNewBlock_slider {
869
+ margin-left: 0;
870
+ width: 100%;
871
+ }
872
+ .pc-SliderNewBlock_type_fullscreen-card:hover .pc-SliderNewBlock__arrow {
873
+ display: none;
874
+ }
875
+ }
876
+ @media (max-width: 577px) {
877
+ .pc-SliderNewBlock_type_fullscreen-card:not(.pc-SliderNewBlock_one-slide) .pc-SliderNewBlock__slider {
878
+ margin-left: 0;
879
+ }
880
+ .pc-SliderNewBlock_type_fullscreen-card:not(.pc-SliderNewBlock_one-slide) .swiper-wrapper {
881
+ padding-left: 0;
804
882
  }
805
883
  }
806
884
  @media (max-width: 769px) {
@@ -821,8 +899,11 @@ unpredictable css rules order in build */
821
899
  overflow-x: auto;
822
900
  }
823
901
  .pc-SliderNewBlock:not(.pc-SliderNewBlock_one-slide) .pc-SliderNewBlock__slider {
824
- padding: 24px 24px 48px;
825
- margin: 0 0 0 -24px;
902
+ margin-left: -24px;
903
+ margin-right: 0;
904
+ }
905
+ .pc-SliderNewBlock:not(.pc-SliderNewBlock_one-slide) .swiper-wrapper {
906
+ padding-left: 16px;
826
907
  }
827
908
  .pc-SliderNewBlock:not(.pc-SliderNewBlock_one-slide) .pc-SliderNewBlock__slide {
828
909
  padding: 0 8px;
@@ -8,6 +8,7 @@ export interface SliderNewProps extends Omit<SliderParams, 'children'>, Partial<
8
8
  dotsClassName?: string;
9
9
  blockClassName?: string;
10
10
  arrowSize?: number;
11
+ initialSlide?: number;
11
12
  }
12
- export declare const SliderNewBlock: ({ animated, title, description, type, anchorId, arrows, adaptive, autoplay: autoplayMs, dots, className, dotsClassName, disclaimer, children, blockClassName, arrowSize, slidesToShow, onSlideChange, onSlideChangeTransitionStart, onSlideChangeTransitionEnd, onActiveIndexChange, onBreakpoint, }: PropsWithChildren<SliderNewProps>) => JSX.Element;
13
+ export declare const SliderNewBlock: ({ animated, title, description, type, anchorId, arrows, adaptive, autoplay: autoplayMs, dots, initialSlide, className, dotsClassName, disclaimer, children, blockClassName, arrowSize, slidesToShow, onSlideChange, onSlideChangeTransitionStart, onSlideChangeTransitionEnd, onActiveIndexChange, onBreakpoint, }: PropsWithChildren<SliderNewProps>) => JSX.Element;
13
14
  export default SliderNewBlock;
@@ -8,19 +8,32 @@ const react_2 = require("swiper/react");
8
8
  const Anchor_1 = tslib_1.__importDefault(require("../../components/Anchor/Anchor"));
9
9
  const AnimateBlock_1 = tslib_1.__importDefault(require("../../components/AnimateBlock/AnimateBlock"));
10
10
  const Title_1 = tslib_1.__importDefault(require("../../components/Title/Title"));
11
+ const models_1 = require("../../models");
11
12
  const utils_1 = require("../../utils");
12
13
  const Arrow_1 = tslib_1.__importDefault(require("./Arrow/Arrow"));
14
+ const i18n_1 = require("./i18n");
13
15
  const useSlider_1 = require("./useSlider");
16
+ const useSliderPagination_1 = require("./useSliderPagination");
14
17
  require("swiper/swiper-bundle.css");
15
18
  const b = (0, utils_1.block)('SliderNewBlock');
16
19
  swiper_1.default.use([swiper_1.Autoplay, swiper_1.A11y, swiper_1.Pagination]);
17
- const SliderNewBlock = ({ animated, title, description, type, anchorId, arrows = true, adaptive, autoplay: autoplayMs, dots = true, className, dotsClassName, disclaimer, children, blockClassName, arrowSize, slidesToShow, onSlideChange, onSlideChangeTransitionStart, onSlideChangeTransitionEnd, onActiveIndexChange, onBreakpoint, }) => {
18
- const { childrenCount, breakpoints, autoplay, onSwiper, onPrev, onNext, isLocked, setIsLocked } = (0, useSlider_1.useSlider)({
20
+ const SliderNewBlock = ({ animated, title, description, type, anchorId, arrows = true, adaptive, autoplay: autoplayMs, dots = true, initialSlide = 0, className, dotsClassName, disclaimer, children, blockClassName, arrowSize, slidesToShow, onSlideChange, onSlideChangeTransitionStart, onSlideChangeTransitionEnd, onActiveIndexChange, onBreakpoint, }) => {
21
+ const { autoplay, isLocked, childrenCount, breakpoints, onSwiper, onPrev, onNext, setIsLocked } = (0, useSlider_1.useSlider)({
19
22
  slidesToShow,
20
23
  children,
21
24
  type,
22
25
  autoplayMs,
23
26
  });
27
+ const isA11yControlHidden = Boolean(autoplay);
28
+ const controlTabIndex = isA11yControlHidden ? -1 : 0;
29
+ const paginationProps = (0, useSliderPagination_1.useSliderPagination)({
30
+ enabled: dots,
31
+ isA11yControlHidden,
32
+ controlTabIndex,
33
+ bulletClass: b('dot', dotsClassName),
34
+ bulletActiveClass: b('dot_active'),
35
+ paginationLabel: (0, i18n_1.i18n)('pagination-label'),
36
+ });
24
37
  return (react_1.default.createElement("div", { className: b({
25
38
  'one-slide': childrenCount === 1,
26
39
  'only-arrows': !(title === null || title === void 0 ? void 0 : title.text) && !description && arrows,
@@ -30,14 +43,14 @@ const SliderNewBlock = ({ animated, title, description, type, anchorId, arrows =
30
43
  anchorId && react_1.default.createElement(Anchor_1.default, { id: anchorId }),
31
44
  react_1.default.createElement(Title_1.default, { title: title, subtitle: description, className: b('header', { 'no-description': !description }) }),
32
45
  react_1.default.createElement(AnimateBlock_1.default, { className: b('animate-slides'), animate: animated },
33
- react_1.default.createElement(react_2.Swiper, { className: b('slider', className), onSwiper: onSwiper, pagination: dots && {
34
- clickable: true,
35
- bulletClass: b('dot', dotsClassName),
36
- bulletActiveClass: b('dot_active'),
37
- }, speed: 1000, autoplay: autoplay, autoHeight: adaptive, initialSlide: 0, noSwiping: false, breakpoints: breakpoints, onSlideChange: onSlideChange, onSlideChangeTransitionStart: onSlideChangeTransitionStart, onSlideChangeTransitionEnd: onSlideChangeTransitionEnd, onActiveIndexChange: onActiveIndexChange, onBreakpoint: onBreakpoint, onLock: () => setIsLocked(true), onUnlock: () => setIsLocked(false), watchSlidesVisibility: true, watchOverflow: true }, react_1.default.Children.map(children, (elem, index) => (react_1.default.createElement(react_2.SwiperSlide, { className: b('slide'), key: index }, elem)))),
46
+ react_1.default.createElement(react_2.Swiper, Object.assign({ className: b('slider', className), onSwiper: onSwiper, speed: 1000, autoplay: autoplay, autoHeight: adaptive, initialSlide: initialSlide, noSwiping: false, breakpoints: breakpoints, onSlideChange: onSlideChange, onSlideChangeTransitionStart: onSlideChangeTransitionStart, onSlideChangeTransitionEnd: onSlideChangeTransitionEnd, onActiveIndexChange: onActiveIndexChange, onBreakpoint: onBreakpoint, onLock: () => setIsLocked(true), onUnlock: () => setIsLocked(false), watchSlidesVisibility: true, watchOverflow: true, a11y: {
47
+ slideLabelMessage: '',
48
+ paginationBulletMessage: (0, i18n_1.i18n)('dot-label', { index: '{{index}}' }),
49
+ } }, paginationProps), react_1.default.Children.map(children, (elem, index) => (react_1.default.createElement(react_2.SwiperSlide, { className: b('slide'), key: index }, ({ isVisible }) => (react_1.default.createElement("div", { className: b('slide-item'), "aria-hidden": !isA11yControlHidden && !isVisible }, elem)))))),
38
50
  arrows && !isLocked && (react_1.default.createElement(react_1.Fragment, null,
39
- react_1.default.createElement(Arrow_1.default, { className: b('arrow', { prev: true }), type: "left", onClick: onPrev, size: arrowSize }),
40
- react_1.default.createElement(Arrow_1.default, { className: b('arrow', { next: true }), type: "right", onClick: onNext, size: arrowSize }))),
51
+ react_1.default.createElement("div", { "aria-hidden": isA11yControlHidden },
52
+ react_1.default.createElement(Arrow_1.default, { className: b('arrow', { prev: true }), type: "left", transparent: type === models_1.SliderType.HeaderCard, onClick: onPrev, size: arrowSize, extraProps: { tabIndex: controlTabIndex } }),
53
+ react_1.default.createElement(Arrow_1.default, { className: b('arrow', { next: true }), type: "right", transparent: type === models_1.SliderType.HeaderCard, onClick: onNext, size: arrowSize, extraProps: { tabIndex: controlTabIndex } })))),
41
54
  react_1.default.createElement("div", { className: b('footer') }, disclaimer ? (react_1.default.createElement("div", { className: b('disclaimer', { size: (disclaimer === null || disclaimer === void 0 ? void 0 : disclaimer.size) || 'm' }) }, disclaimer === null || disclaimer === void 0 ? void 0 : disclaimer.text)) : null))));
42
55
  };
43
56
  exports.SliderNewBlock = SliderNewBlock;
@@ -1,4 +1,6 @@
1
1
  {
2
2
  "arrow-right": "Next",
3
- "arrow-left": "Previous"
3
+ "arrow-left": "Previous",
4
+ "dot-label": "Page {{index}}",
5
+ "pagination-label": "Pages"
4
6
  }
@@ -1 +1 @@
1
- export declare const i18n: (key: "arrow-right" | "arrow-left", params?: import("@gravity-ui/i18n").Params | undefined) => string;
1
+ export declare const i18n: (key: "arrow-right" | "arrow-left" | "dot-label" | "pagination-label", params?: import("@gravity-ui/i18n").Params | undefined) => string;
@@ -1,4 +1,6 @@
1
1
  {
2
2
  "arrow-right": "Дальше",
3
- "arrow-left": "Назад"
3
+ "arrow-left": "Назад",
4
+ "dot-label": "Страница {{index}}",
5
+ "pagination-label": "Страницы"
4
6
  }
@@ -1,11 +1,12 @@
1
1
  import React, { PropsWithChildren } from 'react';
2
2
  import type { Swiper } from 'swiper';
3
3
  import { SlidesToShow } from '../../models';
4
- export declare const useSlider: ({ children, autoplayMs, type, slidesToShow, }: React.PropsWithChildren<{
5
- autoplayMs?: number | undefined;
6
- type?: string | undefined;
7
- slidesToShow?: SlidesToShow | undefined;
8
- }>) => {
4
+ type UseSliderProps = PropsWithChildren<{
5
+ autoplayMs?: number;
6
+ type?: string;
7
+ slidesToShow?: SlidesToShow;
8
+ }>;
9
+ export declare const useSlider: ({ children, autoplayMs, type, ...props }: UseSliderProps) => {
9
10
  slider: Swiper | undefined;
10
11
  onSwiper: React.Dispatch<React.SetStateAction<Swiper | undefined>>;
11
12
  onNext: () => void;
@@ -15,7 +16,8 @@ export declare const useSlider: ({ children, autoplayMs, type, slidesToShow, }:
15
16
  isLocked: boolean;
16
17
  setIsLocked: React.Dispatch<React.SetStateAction<boolean>>;
17
18
  autoplay: false | {
18
- delay: number | undefined;
19
+ delay: number;
19
20
  disableOnInteraction: boolean;
20
21
  };
21
22
  };
23
+ export {};
@@ -5,11 +5,13 @@ const tslib_1 = require("tslib");
5
5
  const react_1 = tslib_1.__importStar(require("react"));
6
6
  const models_1 = require("../../models");
7
7
  const utils_1 = require("./utils");
8
- const useSlider = ({ children, autoplayMs, type, slidesToShow, }) => {
8
+ const useSlider = (_a) => {
9
+ var { children, autoplayMs, type } = _a, props = tslib_1.__rest(_a, ["children", "autoplayMs", "type"]);
9
10
  const [slider, setSlider] = (0, react_1.useState)();
10
11
  const [isLocked, setIsLocked] = (0, react_1.useState)(false);
12
+ const slidesToShow = (0, utils_1.useMemoized)(props.slidesToShow);
11
13
  const childrenCount = react_1.default.Children.count(children);
12
- const autoplayEnabled = (0, react_1.useMemo)(() => Boolean(autoplayMs), [autoplayMs]);
14
+ const autoplayEnabled = autoplayMs !== undefined && autoplayMs > 0;
13
15
  const breakpoints = (0, react_1.useMemo)(() => {
14
16
  return (0, utils_1.getSliderResponsiveParams)({
15
17
  contentLength: childrenCount,
@@ -0,0 +1,9 @@
1
+ import { Swiper as SwiperProps } from 'swiper/swiper-react';
2
+ export declare const useSliderPagination: (props: {
3
+ enabled: boolean;
4
+ isA11yControlHidden: boolean;
5
+ controlTabIndex: number;
6
+ bulletClass: string;
7
+ bulletActiveClass: string;
8
+ paginationLabel: string;
9
+ }) => Pick<SwiperProps, 'pagination' | 'onPaginationUpdate'> | undefined;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useSliderPagination = void 0;
4
+ const utils_1 = require("./utils");
5
+ const useSliderPagination = (props) => {
6
+ if (!props.enabled) {
7
+ return undefined;
8
+ }
9
+ const { isA11yControlHidden, controlTabIndex, bulletClass, bulletActiveClass, paginationLabel } = props;
10
+ return {
11
+ pagination: {
12
+ clickable: true,
13
+ bulletClass,
14
+ bulletActiveClass,
15
+ },
16
+ onPaginationUpdate: (slider) => {
17
+ const pagination = slider.pagination.el;
18
+ (0, utils_1.setElementAtrributes)(pagination, {
19
+ role: 'menu',
20
+ 'aria-hidden': isA11yControlHidden,
21
+ 'aria-label': paginationLabel,
22
+ });
23
+ const bullets = pagination.querySelectorAll(`.${bulletClass}`);
24
+ bullets.forEach((bullet) => {
25
+ const isActive = bullet.classList.contains(bulletActiveClass);
26
+ (0, utils_1.setElementAtrributes)(bullet, {
27
+ role: 'menuitemradio',
28
+ 'aria-hidden': isA11yControlHidden,
29
+ 'aria-checked': isActive,
30
+ tabindex: controlTabIndex,
31
+ });
32
+ });
33
+ },
34
+ };
35
+ };
36
+ exports.useSliderPagination = useSliderPagination;
@@ -12,3 +12,5 @@ export interface GetSlidesToShowParams {
12
12
  mobileFullscreen?: boolean;
13
13
  }
14
14
  export declare function getSliderResponsiveParams({ contentLength, slidesToShow, mobileFullscreen, }: GetSlidesToShowParams): Record<number, SwiperOptions>;
15
+ export declare const useMemoized: <T>(value: T) => T;
16
+ export declare const setElementAtrributes: (element: Element, attributes: Record<string, unknown>) => void;
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getSliderResponsiveParams = exports.DEFAULT_SLIDE_BREAKPOINTS = void 0;
3
+ exports.setElementAtrributes = exports.useMemoized = exports.getSliderResponsiveParams = exports.DEFAULT_SLIDE_BREAKPOINTS = void 0;
4
4
  const tslib_1 = require("tslib");
5
+ const react_1 = require("react");
6
+ const isEqual_1 = tslib_1.__importDefault(require("lodash/isEqual"));
5
7
  const pickBy_1 = tslib_1.__importDefault(require("lodash/pickBy"));
6
8
  const constants_1 = require("../../constants");
7
9
  const models_1 = require("./models");
@@ -29,3 +31,13 @@ function getSliderResponsiveParams({ contentLength, slidesToShow, mobileFullscre
29
31
  }, {});
30
32
  }
31
33
  exports.getSliderResponsiveParams = getSliderResponsiveParams;
34
+ const useMemoized = (value) => {
35
+ const [memoizedValue, setMemoizedValue] = (0, react_1.useState)(value);
36
+ (0, react_1.useEffect)(() => {
37
+ setMemoizedValue((memoized) => value && typeof value === 'object' && (0, isEqual_1.default)(memoized, value) ? memoized : value);
38
+ }, [value]);
39
+ return memoizedValue;
40
+ };
41
+ exports.useMemoized = useMemoized;
42
+ const setElementAtrributes = (element, attributes) => Object.entries(attributes).forEach(([attribute, value]) => element.setAttribute(attribute, String(value)));
43
+ exports.setElementAtrributes = setElementAtrributes;
@@ -12,6 +12,25 @@ unpredictable css rules order in build */
12
12
  .pc-fullscreen-image__modal-content {
13
13
  position: relative;
14
14
  border-radius: var(--pc-border-radius);
15
+ width: 100%;
16
+ }
17
+ .pc-fullscreen-image__modal-content-wrapper {
18
+ width: 100%;
19
+ }
20
+ .pc-fullscreen-image__modal-content_loaded {
21
+ max-width: fit-content;
22
+ }
23
+ .pc-fullscreen-image__modal_with-slider .g-modal__content-wrapper {
24
+ width: 100%;
25
+ height: 100vh;
26
+ margin: 0;
27
+ justify-content: center;
28
+ }
29
+ .pc-fullscreen-image__modal_with-slider .pc-fullscreen-image__modal-content {
30
+ background-color: transparent;
31
+ }
32
+ .pc-fullscreen-image__modal_with-slider .pc-fullscreen-image__modal-content:hover .pc-fullscreen-image__icon-wrapper {
33
+ opacity: 1;
15
34
  }
16
35
  .pc-fullscreen-image__modal-image {
17
36
  display: block;
@@ -19,6 +38,27 @@ unpredictable css rules order in build */
19
38
  max-height: 70vh;
20
39
  overflow: hidden;
21
40
  }
41
+ .pc-fullscreen-image__modal-slider {
42
+ max-width: 100vw;
43
+ width: 100%;
44
+ height: 100vh;
45
+ }
46
+ .pc-fullscreen-image__modal-slider_item {
47
+ height: 100%;
48
+ display: flex;
49
+ justify-content: center;
50
+ align-items: center;
51
+ }
52
+ .pc-fullscreen-image__modal-slider_item-image {
53
+ display: block;
54
+ margin: auto;
55
+ border-radius: var(--pc-border-radius);
56
+ overflow: hidden;
57
+ max-height: calc(100vh - 80px);
58
+ max-width: 100%;
59
+ object-fit: contain;
60
+ object-position: center;
61
+ }
22
62
  .pc-fullscreen-image__modal .g-modal__content, .pc-fullscreen-image__modal-image {
23
63
  border-radius: var(--pc-border-radius);
24
64
  }
@@ -36,6 +76,7 @@ unpredictable css rules order in build */
36
76
  align-items: center;
37
77
  justify-content: center;
38
78
  position: absolute;
79
+ z-index: 1001;
39
80
  right: 16px;
40
81
  top: 16px;
41
82
  width: 36px;
@@ -56,6 +97,10 @@ unpredictable css rules order in build */
56
97
  .pc-fullscreen-image__icon-wrapper:focus {
57
98
  opacity: 1;
58
99
  }
100
+ .pc-fullscreen-image__icon-wrapper_visible {
101
+ right: 24px;
102
+ top: 24px;
103
+ }
59
104
  .pc-fullscreen-image__icon {
60
105
  color: var(--g-color-text-hint);
61
106
  }
@@ -67,14 +112,9 @@ unpredictable css rules order in build */
67
112
  width: 100%;
68
113
  }
69
114
  }
70
- @media (max-width: 1081px) {
71
- .pc-fullscreen-image__image {
72
- pointer-events: none;
73
- }
115
+ @media (max-width: 769px) {
74
116
  .pc-fullscreen-image__icon-wrapper {
75
- display: none;
76
- }
77
- .pc-fullscreen-image__modal {
78
- display: none !important; /* stylelint-disable-line declaration-no-important */
117
+ right: 20px;
118
+ top: 50px;
79
119
  }
80
120
  }
@@ -1,10 +1,15 @@
1
1
  import { CSSProperties, HTMLProps } from 'react';
2
+ import { ImageProps as ModelImageProps } from '../../models';
2
3
  import { ImageProps } from '../Image/Image';
3
4
  export interface FullscreenImageProps extends ImageProps {
4
5
  imageClassName?: string;
5
6
  modalImageClass?: string;
6
7
  imageStyle?: CSSProperties;
7
8
  extraProps?: HTMLProps<HTMLDivElement>;
9
+ sliderData?: {
10
+ items: ModelImageProps[];
11
+ initialIndex: number;
12
+ };
8
13
  }
9
14
  declare const FullscreenImage: (props: FullscreenImageProps) => JSX.Element;
10
15
  export default FullscreenImage;
@@ -4,25 +4,39 @@ const tslib_1 = require("tslib");
4
4
  const react_1 = tslib_1.__importStar(require("react"));
5
5
  const icons_1 = require("@gravity-ui/icons");
6
6
  const uikit_1 = require("@gravity-ui/uikit");
7
+ const unstable_1 = require("../../blocks/unstable");
8
+ const models_1 = require("../../models");
7
9
  const utils_1 = require("../../utils");
8
10
  const Image_1 = tslib_1.__importDefault(require("../Image/Image"));
11
+ const utils_2 = require("../Media/Image/utils");
9
12
  const i18n_1 = require("./i18n");
10
13
  const b = (0, utils_1.block)('fullscreen-image');
11
14
  const FULL_SCREEN_ICON_SIZE = 18;
12
15
  const CLOSE_ICON_SIZE = 24;
13
16
  const FullscreenImage = (props) => {
14
- const { imageClassName, modalImageClass, imageStyle, alt = (0, i18n_1.i18n)('img-alt'), extraProps } = props;
17
+ const { imageClassName, sliderData, modalImageClass, imageStyle, alt = (0, i18n_1.i18n)('img-alt'), extraProps, } = props;
15
18
  const [isOpened, setIsOpened] = (0, react_1.useState)(false);
19
+ const [sliderLoaded, setSliderLoaded] = (0, react_1.useState)(false);
16
20
  const openModal = () => setIsOpened(true);
17
21
  const closeModal = () => setIsOpened(false);
22
+ (0, react_1.useEffect)(() => {
23
+ if (sliderData && !isOpened) {
24
+ setSliderLoaded(false);
25
+ }
26
+ }, [isOpened, sliderData]);
27
+ const handleSliderImageLoad = () => {
28
+ setSliderLoaded(true);
29
+ };
18
30
  return (react_1.default.createElement("div", Object.assign({ className: b() }, extraProps),
19
31
  react_1.default.createElement("div", { className: b('image-wrapper') },
20
32
  react_1.default.createElement(Image_1.default, Object.assign({}, props, { alt: alt, className: b('image', imageClassName), onClick: openModal, style: imageStyle })),
21
33
  react_1.default.createElement("button", { className: b('icon-wrapper'), onClick: openModal },
22
34
  react_1.default.createElement(uikit_1.Icon, { data: icons_1.ChevronsExpandUpRight, width: FULL_SCREEN_ICON_SIZE, height: FULL_SCREEN_ICON_SIZE, className: b('icon') }))),
23
- isOpened && (react_1.default.createElement(uikit_1.Modal, { open: isOpened, onClose: closeModal, className: b('modal'), contentClassName: b('modal-content') },
35
+ isOpened && (react_1.default.createElement(uikit_1.Modal, { open: isOpened, onClose: closeModal, className: b('modal', { 'with-slider': Boolean(sliderData) }), contentClassName: b('modal-content', { loaded: sliderLoaded }) },
24
36
  react_1.default.createElement("button", { className: b('icon-wrapper', { visible: true }), onClick: closeModal, "aria-label": (0, i18n_1.i18n)('close') },
25
37
  react_1.default.createElement(uikit_1.Icon, { data: icons_1.Xmark, width: CLOSE_ICON_SIZE, height: CLOSE_ICON_SIZE, className: b('icon', { hover: true }) })),
26
- react_1.default.createElement(Image_1.default, Object.assign({}, props, { className: b('modal-image', modalImageClass) }))))));
38
+ sliderData ? (react_1.default.createElement("div", { className: b('modal-slider') },
39
+ react_1.default.createElement(unstable_1.SliderNewBlock, { initialSlide: sliderData.initialIndex, slidesToShow: 1, type: models_1.SliderType.FullscreenCard }, sliderData.items.map((item, index) => (react_1.default.createElement("div", { key: index, className: b('modal-slider_item') },
40
+ react_1.default.createElement(Image_1.default, Object.assign({ onLoad: handleSliderImageLoad, className: b('modal-slider_item-image', modalImageClass), containerClassName: b('modal-slider_item-image-wrapper') }, (0, utils_2.getMediaImage)(item))))))))) : (react_1.default.createElement(Image_1.default, Object.assign({}, props, { className: b('modal-image', modalImageClass) })))))));
27
41
  };
28
42
  exports.default = FullscreenImage;
@@ -3,6 +3,7 @@ export interface ImageAdditionProps {
3
3
  imageClassName?: string;
4
4
  isBackground?: boolean;
5
5
  fullscreen?: boolean;
6
+ fullscreenClassName?: string;
6
7
  onLoad?: () => void;
7
8
  }
8
9
  interface InnerImageProps {
@@ -5,7 +5,7 @@ const tslib_1 = require("tslib");
5
5
  const react_1 = tslib_1.__importStar(require("react"));
6
6
  const web_1 = require("@react-spring/web");
7
7
  const debounce_1 = tslib_1.__importDefault(require("lodash/debounce"));
8
- const Slider_1 = tslib_1.__importDefault(require("../../../blocks/Slider/Slider"));
8
+ const unstable_1 = require("../../../blocks/unstable");
9
9
  const models_1 = require("../../../models");
10
10
  const utils_1 = require("../../../utils");
11
11
  const BackgroundImage_1 = tslib_1.__importDefault(require("../../BackgroundImage/BackgroundImage"));
@@ -15,7 +15,7 @@ const utils_2 = require("./utils");
15
15
  const b = (0, utils_1.block)('media-component-image');
16
16
  exports.defaultAnimatedDivQa = 'animated-div';
17
17
  const Image = (props) => {
18
- const { parallax, height, imageClassName, isBackground, hasVideoFallback, video, fullscreen, disableImageSliderForArrayInput, qa, onLoad, } = props;
18
+ const { parallax, height, imageClassName, fullscreenClassName, isBackground, hasVideoFallback, video, fullscreen, disableImageSliderForArrayInput, qa, onLoad, } = props;
19
19
  const image = Array.isArray(props.image) && disableImageSliderForArrayInput
20
20
  ? props.image[0]
21
21
  : props.image;
@@ -41,9 +41,9 @@ const Image = (props) => {
41
41
  parallaxInterpolate = springScrollY.to((value) => `translateY(-${Number(value) / parallaxLevel}px)`);
42
42
  }
43
43
  const imageClass = b('item', { withVideo: Boolean(video) && !hasVideoFallback }, imageClassName);
44
- const renderFullscreenImage = (item) => {
44
+ const renderFullscreenImage = (item, sliderData) => {
45
45
  const itemData = (0, utils_2.getMediaImage)(item);
46
- return (react_1.default.createElement(FullscreenImage_1.default, Object.assign({ key: itemData.alt }, itemData, { imageClassName: imageClass, imageStyle: { height }, qa: qaAttributes.fullscreenImage })));
46
+ return (react_1.default.createElement(FullscreenImage_1.default, Object.assign({ key: itemData.alt }, itemData, { imageClassName: imageClass, modalImageClass: fullscreenClassName, imageStyle: { height }, qa: qaAttributes.fullscreenImage, sliderData: sliderData })));
47
47
  };
48
48
  const imageBackground = (oneImage) => {
49
49
  const imageData = (0, utils_2.getMediaImage)(oneImage);
@@ -56,7 +56,9 @@ const Image = (props) => {
56
56
  };
57
57
  const imageSlider = (imageArray) => {
58
58
  const fullscreenItem = fullscreen === undefined || fullscreen;
59
- return (react_1.default.createElement(Slider_1.default, { slidesToShow: 1, type: models_1.SliderType.MediaCard }, imageArray.map((item, index) => (react_1.default.createElement(react_1.Fragment, { key: index }, fullscreenItem ? renderFullscreenImage(item) : imageOnly(item))))));
59
+ return (react_1.default.createElement(unstable_1.SliderNewBlock, { slidesToShow: 1, type: models_1.SliderType.MediaCard }, imageArray.map((item, index) => (react_1.default.createElement(react_1.Fragment, { key: index }, fullscreenItem
60
+ ? renderFullscreenImage(item, { items: imageArray, initialIndex: index })
61
+ : imageOnly(item))))));
60
62
  };
61
63
  if (Array.isArray(image)) {
62
64
  return imageSlider(image);
@@ -8,4 +8,8 @@ unpredictable css rules order in build */
8
8
  overflow: hidden;
9
9
  display: flex;
10
10
  align-items: center;
11
+ }
12
+ .pc-Media__fullscreen-image-cover {
13
+ object-fit: cover;
14
+ object-position: top;
11
15
  }
@@ -3,6 +3,7 @@ import { ImageAdditionProps } from './Image/Image';
3
3
  import { VideoAdditionProps } from './Video/Video';
4
4
  export interface MediaAllProps extends MediaProps, VideoAdditionProps, ImageAdditionProps, QAProps {
5
5
  className?: string;
6
+ isFullscreenImageCover?: boolean;
6
7
  youtubeClassName?: string;
7
8
  autoplay?: boolean;
8
9
  onImageLoad?: () => void;
@@ -12,13 +12,13 @@ const Image_1 = tslib_1.__importDefault(require("./Image/Image"));
12
12
  const Video_1 = tslib_1.__importDefault(require("./Video/Video"));
13
13
  const b = (0, utils_1.block)('Media');
14
14
  const Media = (props) => {
15
- const { image, video, youtube, videoIframe, dataLens, color, height, previewImg, parallax = false, fullscreen, analyticsEvents, className, imageClassName, videoClassName, youtubeClassName, disableImageSliderForArrayInput, playVideo = true, isBackground, playButton, customBarControlsClassName, qa, ratio, autoplay, onImageLoad, iframe, margins, } = props;
15
+ const { image, video, youtube, videoIframe, dataLens, color, height, previewImg, parallax = false, fullscreen, isFullscreenImageCover, analyticsEvents, className, imageClassName, videoClassName, youtubeClassName, disableImageSliderForArrayInput, playVideo = true, isBackground, playButton, customBarControlsClassName, qa, ratio, autoplay, onImageLoad, iframe, margins, } = props;
16
16
  const [hasVideoFallback, setHasVideoFallback] = (0, react_1.useState)(false);
17
17
  const qaAttributes = (0, utils_1.getQaAttrubutes)(qa, 'video');
18
18
  const content = (0, react_1.useMemo)(() => {
19
19
  let result = [];
20
20
  if (image) {
21
- result.push(react_1.default.createElement(Image_1.default, { key: "image", parallax: parallax, image: image, disableImageSliderForArrayInput: disableImageSliderForArrayInput, height: height, imageClassName: imageClassName, isBackground: isBackground, video: video, hasVideoFallback: hasVideoFallback, fullscreen: fullscreen, qa: qaAttributes.image, onLoad: onImageLoad }));
21
+ result.push(react_1.default.createElement(Image_1.default, { key: "image", parallax: parallax, image: image, disableImageSliderForArrayInput: disableImageSliderForArrayInput, height: height, imageClassName: imageClassName, fullscreenClassName: isFullscreenImageCover ? b('fullscreen-image-cover') : undefined, isBackground: isBackground, video: video, hasVideoFallback: hasVideoFallback, fullscreen: fullscreen, qa: qaAttributes.image, onLoad: onImageLoad }));
22
22
  }
23
23
  if (video) {
24
24
  const videoProps = {
@@ -66,6 +66,7 @@ const Media = (props) => {
66
66
  isBackground,
67
67
  hasVideoFallback,
68
68
  fullscreen,
69
+ isFullscreenImageCover,
69
70
  qaAttributes.image,
70
71
  qaAttributes.video,
71
72
  onImageLoad,