@alfalab/core-components-gallery 1.1.0 → 2.0.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 (110) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/dist/Component.d.ts +2 -0
  3. package/dist/Component.js +6 -5
  4. package/dist/components/header/Component.js +11 -7
  5. package/dist/components/header/buttons.js +1 -1
  6. package/dist/components/header/index.css +3 -3
  7. package/dist/components/header/index.js +2 -1
  8. package/dist/components/header-info-block/Component.js +1 -1
  9. package/dist/components/header-info-block/index.css +5 -5
  10. package/dist/components/image-preview/Component.js +1 -1
  11. package/dist/components/image-preview/index.css +13 -12
  12. package/dist/components/image-viewer/component.js +15 -7
  13. package/dist/components/image-viewer/index.css +19 -20
  14. package/dist/components/image-viewer/index.js +3 -2
  15. package/dist/components/image-viewer/slide.js +2 -1
  16. package/dist/components/index.js +3 -2
  17. package/dist/components/navigation-bar/Component.js +3 -2
  18. package/dist/components/navigation-bar/index.css +6 -6
  19. package/dist/components/navigation-bar/index.js +1 -0
  20. package/dist/cssm/Component.d.ts +2 -0
  21. package/dist/cssm/Component.js +3 -2
  22. package/dist/cssm/components/header/Component.js +9 -5
  23. package/dist/cssm/components/header/index.js +1 -0
  24. package/dist/cssm/components/header/index.module.css +1 -1
  25. package/dist/cssm/components/image-preview/index.module.css +1 -0
  26. package/dist/cssm/components/image-viewer/component.js +13 -5
  27. package/dist/cssm/components/image-viewer/index.js +1 -0
  28. package/dist/cssm/components/image-viewer/index.module.css +0 -1
  29. package/dist/cssm/components/image-viewer/slide.d.ts +1 -0
  30. package/dist/cssm/components/image-viewer/slide.js +5 -6
  31. package/dist/cssm/components/index.js +1 -0
  32. package/dist/cssm/components/navigation-bar/Component.js +2 -1
  33. package/dist/cssm/components/navigation-bar/index.js +1 -0
  34. package/dist/cssm/index.d.ts +1 -0
  35. package/dist/cssm/index.js +10 -2
  36. package/dist/cssm/types.d.ts +1 -0
  37. package/dist/cssm/utils/constants.d.ts +11 -0
  38. package/dist/cssm/utils/constants.js +16 -0
  39. package/dist/cssm/utils/index.d.ts +1 -0
  40. package/dist/cssm/utils/index.js +2 -0
  41. package/dist/esm/Component.d.ts +2 -0
  42. package/dist/esm/Component.js +6 -5
  43. package/dist/esm/components/header/Component.js +11 -7
  44. package/dist/esm/components/header/buttons.js +1 -1
  45. package/dist/esm/components/header/index.css +3 -3
  46. package/dist/esm/components/header/index.js +2 -1
  47. package/dist/esm/components/header-info-block/Component.js +1 -1
  48. package/dist/esm/components/header-info-block/index.css +5 -5
  49. package/dist/esm/components/image-preview/Component.js +1 -1
  50. package/dist/esm/components/image-preview/index.css +13 -12
  51. package/dist/esm/components/image-viewer/component.js +15 -7
  52. package/dist/esm/components/image-viewer/index.css +19 -20
  53. package/dist/esm/components/image-viewer/index.js +3 -2
  54. package/dist/esm/components/image-viewer/slide.js +2 -1
  55. package/dist/esm/components/index.js +3 -2
  56. package/dist/esm/components/navigation-bar/Component.js +3 -2
  57. package/dist/esm/components/navigation-bar/index.css +6 -6
  58. package/dist/esm/components/navigation-bar/index.js +1 -0
  59. package/dist/esm/index.css +3 -3
  60. package/dist/esm/index.d.ts +1 -0
  61. package/dist/esm/index.js +5 -4
  62. package/dist/esm/{slide-cafe0061.d.ts → slide-0d407884.d.ts} +1 -0
  63. package/dist/esm/{slide-cafe0061.js → slide-0d407884.js} +6 -7
  64. package/dist/esm/{tslib.es6-da013922.d.ts → tslib.es6-fec9ce55.d.ts} +0 -0
  65. package/dist/esm/{tslib.es6-da013922.js → tslib.es6-fec9ce55.js} +0 -0
  66. package/dist/esm/types.d.ts +1 -0
  67. package/dist/esm/utils/constants.d.ts +11 -0
  68. package/dist/esm/utils/constants.js +12 -0
  69. package/dist/esm/utils/index.d.ts +1 -0
  70. package/dist/esm/utils/index.js +1 -0
  71. package/dist/index.css +3 -3
  72. package/dist/index.d.ts +1 -0
  73. package/dist/index.js +12 -4
  74. package/dist/modern/Component.d.ts +2 -0
  75. package/dist/modern/Component.js +5 -4
  76. package/dist/modern/components/header/Component.js +8 -5
  77. package/dist/modern/components/header/index.css +3 -3
  78. package/dist/modern/components/header/index.js +1 -0
  79. package/dist/modern/components/header-info-block/Component.js +1 -1
  80. package/dist/modern/components/header-info-block/index.css +5 -5
  81. package/dist/modern/components/image-preview/Component.js +1 -1
  82. package/dist/modern/components/image-preview/index.css +13 -12
  83. package/dist/modern/components/image-viewer/component.js +12 -5
  84. package/dist/modern/components/image-viewer/index.css +19 -20
  85. package/dist/modern/components/image-viewer/index.js +2 -1
  86. package/dist/modern/components/image-viewer/slide.js +2 -1
  87. package/dist/modern/components/index.js +2 -1
  88. package/dist/modern/components/navigation-bar/Component.js +3 -2
  89. package/dist/modern/components/navigation-bar/index.css +6 -6
  90. package/dist/modern/components/navigation-bar/index.js +1 -0
  91. package/dist/modern/index.css +3 -3
  92. package/dist/modern/index.d.ts +1 -0
  93. package/dist/modern/index.js +4 -3
  94. package/dist/modern/{slide-db4a1a0f.d.ts → slide-831df2ef.d.ts} +1 -0
  95. package/dist/modern/{slide-db4a1a0f.js → slide-831df2ef.js} +6 -7
  96. package/dist/modern/types.d.ts +1 -0
  97. package/dist/modern/utils/constants.d.ts +11 -0
  98. package/dist/modern/utils/constants.js +12 -0
  99. package/dist/modern/utils/index.d.ts +1 -0
  100. package/dist/modern/utils/index.js +1 -0
  101. package/dist/{slide-dea55470.d.ts → slide-4f1564f2.d.ts} +1 -0
  102. package/dist/{slide-dea55470.js → slide-4f1564f2.js} +6 -7
  103. package/dist/{tslib.es6-24a89a0d.d.ts → tslib.es6-925681d9.d.ts} +0 -0
  104. package/dist/{tslib.es6-24a89a0d.js → tslib.es6-925681d9.js} +0 -0
  105. package/dist/types.d.ts +1 -0
  106. package/dist/utils/constants.d.ts +11 -0
  107. package/dist/utils/constants.js +16 -0
  108. package/dist/utils/index.d.ts +1 -0
  109. package/dist/utils/index.js +2 -0
  110. package/package.json +5 -5
@@ -7,6 +7,7 @@ import './components/image-preview/Component.js';
7
7
  import { NavigationBar } from './components/navigation-bar/Component.js';
8
8
  import './utils/split-filename.js';
9
9
  import './utils/utils.js';
10
+ import './utils/constants.js';
10
11
  import '@alfalab/core-components-typography/dist/modern';
11
12
  import './components/header-info-block/Component.js';
12
13
  import '@alfalab/core-components-icon-button/dist/modern';
@@ -23,10 +24,10 @@ import 'element-closest';
23
24
  import 'swiper/swiper.min.css';
24
25
  import '@alfalab/icons-glyph/ChevronBackHeavyMIcon';
25
26
  import '@alfalab/icons-glyph/ChevronForwardHeavyMIcon';
26
- import './slide-db4a1a0f.js';
27
+ import './slide-831df2ef.js';
27
28
  import { ImageViewer } from './components/image-viewer/component.js';
28
29
 
29
- var styles = {"container":"gallery__container_th1rc","modal":"gallery__modal_th1rc"};
30
+ var styles = {"container":"gallery__container_1g1fk","modal":"gallery__modal_1g1fk"};
30
31
  require('./index.css')
31
32
 
32
33
  const Backdrop = () => null;
@@ -77,7 +78,7 @@ const Gallery = ({ open, images, initialSlide = 0, loop = true, onClose, }) => {
77
78
  }
78
79
  };
79
80
  const handleKeyDown = useCallback((event) => {
80
- if (fullScreen) {
81
+ if (!open || fullScreen) {
81
82
  return;
82
83
  }
83
84
  switch (event.key) {
@@ -88,7 +89,7 @@ const Gallery = ({ open, images, initialSlide = 0, loop = true, onClose, }) => {
88
89
  slideNext();
89
90
  break;
90
91
  }
91
- }, [fullScreen, slideNext, slidePrev]);
92
+ }, [fullScreen, open, slideNext, slidePrev]);
92
93
  useEffect(() => {
93
94
  document.addEventListener('keydown', handleKeyDown);
94
95
  return () => {
@@ -2,6 +2,7 @@ import React, { useContext, useRef, useEffect } from 'react';
2
2
  import { GalleryContext } from '../../context.js';
3
3
  import '../../utils/split-filename.js';
4
4
  import { isSmallImage } from '../../utils/utils.js';
5
+ import { TestIds } from '../../utils/constants.js';
5
6
  import '@alfalab/core-components-typography/dist/modern';
6
7
  import { HeaderInfoBlock } from '../header-info-block/Component.js';
7
8
  import '@alfalab/core-components-icon-button/dist/modern';
@@ -12,7 +13,7 @@ import '@alfalab/icons-glyph/ArrowsInwardMIcon';
12
13
  import '@alfalab/icons-glyph/CrossMIcon';
13
14
  import { ExitFullscreen, Fullscreen, Download, Exit } from './buttons.js';
14
15
 
15
- var styles = {"component":"gallery__component_lb1bj","buttons":"gallery__buttons_lb1bj"};
16
+ var styles = {"header":"gallery__header_iy7z8","buttons":"gallery__buttons_iy7z8"};
16
17
  require('./index.css')
17
18
 
18
19
  const Header = () => {
@@ -30,19 +31,21 @@ const Header = () => {
30
31
  }
31
32
  }, [fullScreen]);
32
33
  const currentImage = getCurrentImage();
34
+ const canDownload = currentImage?.canDownload ?? true;
33
35
  const filename = currentImage?.name || '';
34
36
  const description = singleSlide
35
37
  ? ''
36
38
  : `Изображение ${currentSlideIndex + 1} из ${images.length}`;
37
39
  const meta = getCurrentImageMeta();
38
40
  const showFullScreenButton = !isSmallImage(meta) && !meta?.broken;
39
- const renderToggleFullScreenButton = () => fullScreen ? (React.createElement(ExitFullscreen, { onClick: closeFullScreen, buttonRef: toggleFullScreenButton })) : (React.createElement(Fullscreen, { onClick: openFullScreen, buttonRef: toggleFullScreenButton }));
40
- return (React.createElement("div", { className: styles.component },
41
+ const showDownloadButton = !meta?.broken && canDownload;
42
+ const renderToggleFullScreenButton = () => fullScreen ? (React.createElement(ExitFullscreen, { onClick: closeFullScreen, buttonRef: toggleFullScreenButton, dataTestId: TestIds.EXIT_FULLSCREEN_BUTTON })) : (React.createElement(Fullscreen, { onClick: openFullScreen, buttonRef: toggleFullScreenButton, dataTestId: TestIds.FULLSCREEN_BUTTON }));
43
+ return (React.createElement("div", { className: styles.header },
41
44
  React.createElement(HeaderInfoBlock, { filename: filename, description: description }),
42
45
  React.createElement("div", { className: styles.buttons },
43
46
  showFullScreenButton && renderToggleFullScreenButton(),
44
- !meta?.broken && (React.createElement(Download, { href: currentImage?.src, download: currentImage?.name })),
45
- React.createElement(Exit, { onClick: onClose }))));
47
+ showDownloadButton && (React.createElement(Download, { href: currentImage?.src, download: currentImage?.name, dataTestId: TestIds.DOWNLOAD_BUTTON })),
48
+ React.createElement(Exit, { onClick: onClose, dataTestId: TestIds.CLOSE_BUTTON }))));
46
49
  };
47
50
 
48
51
  export { Header };
@@ -1,4 +1,4 @@
1
- /* hash: lb1bj */
1
+ /* hash: 1oujp */
2
2
  :root {
3
3
  --color-light-bg-tertiary-inverted: #3c4c5d;
4
4
  }
@@ -15,7 +15,7 @@
15
15
  --gap-xl: 24px;
16
16
  --gap-2xl: 32px;
17
17
  }
18
- .gallery__component_lb1bj {
18
+ .gallery__header_iy7z8 {
19
19
  display: flex;
20
20
  justify-content: space-between;
21
21
  flex-shrink: 0;
@@ -24,7 +24,7 @@
24
24
  background-color: var(--color-light-bg-tertiary-inverted);
25
25
  box-sizing: border-box;
26
26
  }
27
- .gallery__buttons_lb1bj {
27
+ .gallery__buttons_iy7z8 {
28
28
  display: flex;
29
29
  padding-left: var(--gap-2xl);
30
30
  }
@@ -2,6 +2,7 @@ import 'react';
2
2
  import '../../context.js';
3
3
  import '../../utils/split-filename.js';
4
4
  import '../../utils/utils.js';
5
+ import '../../utils/constants.js';
5
6
  import '@alfalab/core-components-typography/dist/modern';
6
7
  import '../header-info-block/Component.js';
7
8
  import '@alfalab/core-components-icon-button/dist/modern';
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import { splitFilename } from '../../utils/split-filename.js';
3
3
  import { Typography } from '@alfalab/core-components-typography/dist/modern';
4
4
 
5
- var styles = {"info":"gallery__info_189iu","filenameHead":"gallery__filenameHead_189iu","filenameContainer":"gallery__filenameContainer_189iu","description":"gallery__description_189iu"};
5
+ var styles = {"info":"gallery__info_vpxmu","filenameHead":"gallery__filenameHead_vpxmu","filenameContainer":"gallery__filenameContainer_vpxmu","description":"gallery__description_vpxmu"};
6
6
  require('./index.css')
7
7
 
8
8
  const HeaderInfoBlock = ({ filename, description }) => {
@@ -1,4 +1,4 @@
1
- /* hash: 189iu */
1
+ /* hash: 4q0fv */
2
2
  :root {
3
3
 
4
4
  /* Hard */
@@ -10,24 +10,24 @@
10
10
  :root {
11
11
  --gap-2xs: 4px;
12
12
  }
13
- .gallery__info_189iu {
13
+ .gallery__info_vpxmu {
14
14
  height: 100%;
15
15
  display: flex;
16
16
  flex-direction: column;
17
17
  justify-content: center;
18
18
  overflow: hidden;
19
19
  }
20
- .gallery__filenameHead_189iu {
20
+ .gallery__filenameHead_vpxmu {
21
21
  display: inline;
22
22
  text-overflow: ellipsis;
23
23
  overflow: hidden;
24
24
  white-space: nowrap;
25
25
  }
26
- .gallery__filenameContainer_189iu {
26
+ .gallery__filenameContainer_vpxmu {
27
27
  overflow: hidden;
28
28
  display: inline-flex;
29
29
  }
30
- .gallery__description_189iu {
30
+ .gallery__description_vpxmu {
31
31
  display: inline;
32
32
  text-overflow: ellipsis;
33
33
  overflow: hidden;
@@ -3,7 +3,7 @@ import cn from 'classnames';
3
3
  import { useFocus } from '@alfalab/hooks';
4
4
  import { GalleryContext } from '../../context.js';
5
5
 
6
- var styles = {"component":"gallery__component_7nabl","active":"gallery__active_7nabl","image":"gallery__image_7nabl","preview":"gallery__preview_7nabl","loading":"gallery__loading_7nabl","brokenImageWrapper":"gallery__brokenImageWrapper_7nabl","brokenIcon":"gallery__brokenIcon_7nabl","focused":"gallery__focused_7nabl"};
6
+ var styles = {"component":"gallery__component_1b44h","active":"gallery__active_1b44h","image":"gallery__image_1b44h","preview":"gallery__preview_1b44h","loading":"gallery__loading_1b44h","brokenImageWrapper":"gallery__brokenImageWrapper_1b44h","brokenIcon":"gallery__brokenIcon_1b44h","focused":"gallery__focused_1b44h"};
7
7
  require('./index.css')
8
8
 
9
9
  const ImagePreview = ({ image, active = false, index, onSelect, className }) => {
@@ -1,4 +1,4 @@
1
- /* hash: 7nabl */
1
+ /* hash: 134vz */
2
2
  :root {
3
3
  --color-light-bg-primary: #fff;
4
4
  --color-light-border-key-inverted: #fff;
@@ -25,21 +25,22 @@
25
25
  :root {
26
26
  --gallery-broken-image-icon: url('https://alfabank.st/icons/art_no-image_s.svg');
27
27
  }
28
- .gallery__component_7nabl {
28
+ .gallery__component_1b44h {
29
29
  display: flex;
30
30
  padding: var(--gap-2xs);
31
31
  border: 2px solid rgba(0, 0, 0, 0);
32
32
  border-radius: var(--border-radius-l);
33
33
  overflow: hidden;
34
34
  transition: border 0.15s ease-in-out;
35
+ outline: none;
35
36
  }
36
- .gallery__active_7nabl {
37
+ .gallery__active_1b44h {
37
38
  border-color: var(--color-light-border-key-inverted)
38
39
  }
39
- .gallery__active_7nabl > .gallery__image_7nabl {
40
+ .gallery__active_1b44h > .gallery__image_1b44h {
40
41
  opacity: 0.7;
41
42
  }
42
- .gallery__preview_7nabl {
43
+ .gallery__preview_1b44h {
43
44
  width: 56px;
44
45
  height: 56px;
45
46
  flex-shrink: 0;
@@ -48,37 +49,37 @@
48
49
  -webkit-user-select: none;
49
50
  user-select: none;
50
51
  }
51
- .gallery__image_7nabl {
52
+ .gallery__image_1b44h {
52
53
  background-color: var(--color-light-bg-primary);
53
54
  background-size: cover;
54
55
  background-repeat: no-repeat;
55
56
  background-position: center;
56
57
  transition: opacity 0.15s ease-in-out
57
58
  }
58
- .gallery__image_7nabl:hover {
59
+ .gallery__image_1b44h:hover {
59
60
  opacity: 0.7;
60
61
  }
61
- .gallery__loading_7nabl {
62
+ .gallery__loading_1b44h {
62
63
  /* TODO: цвета нет в палитре */
63
64
  background-color: #e9eaeb;
64
65
  }
65
- .gallery__brokenImageWrapper_7nabl {
66
+ .gallery__brokenImageWrapper_1b44h {
66
67
  display: flex;
67
68
  justify-content: center;
68
69
  align-items: center;
69
70
  background-color: var(--color-light-bg-primary)
70
71
  }
71
- .gallery__brokenImageWrapper_7nabl:hover {
72
+ .gallery__brokenImageWrapper_1b44h:hover {
72
73
  opacity: 0.7;
73
74
  }
74
- .gallery__brokenIcon_7nabl {
75
+ .gallery__brokenIcon_1b44h {
75
76
  width: 40px;
76
77
  height: 40px;
77
78
  background-image: var(--gallery-broken-image-icon);
78
79
  background-size: contain;
79
80
  background-repeat: no-repeat;
80
81
  }
81
- .gallery__focused_7nabl {
82
+ .gallery__focused_1b44h {
82
83
  outline: 2px solid var(--focus-color);
83
84
  outline-offset: 2px;
84
85
  }
@@ -3,6 +3,7 @@ import cn from 'classnames';
3
3
  import { useFocus } from '@alfalab/hooks';
4
4
  import { GalleryContext } from '../../context.js';
5
5
  import { getImageAlt, getImageKey } from '../../utils/utils.js';
6
+ import { TestIds } from '../../utils/constants.js';
6
7
  import '@alfalab/core-components-typography/dist/modern';
7
8
  import SwiperCore, { EffectFade, A11y, Controller } from 'swiper';
8
9
  import { Swiper, SwiperSlide } from 'swiper/react';
@@ -10,7 +11,7 @@ import elementClosest from 'element-closest';
10
11
  import 'swiper/swiper.min.css';
11
12
  import { ChevronBackHeavyMIcon } from '@alfalab/icons-glyph/ChevronBackHeavyMIcon';
12
13
  import { ChevronForwardHeavyMIcon } from '@alfalab/icons-glyph/ChevronForwardHeavyMIcon';
13
- import { s as styles, S as Slide } from '../../slide-db4a1a0f.js';
14
+ import { s as styles, S as Slide } from '../../slide-831df2ef.js';
14
15
 
15
16
  SwiperCore.use([EffectFade, A11y, Controller]);
16
17
  const ImageViewer = () => {
@@ -21,7 +22,7 @@ const ImageViewer = () => {
21
22
  const [rightArrowFocused] = useFocus(rightArrowRef, 'keyboard');
22
23
  const swiper = getSwiper();
23
24
  const handleSlideChange = useCallback(() => {
24
- setCurrentSlideIndex(swiper?.activeIndex || initialSlide);
25
+ setCurrentSlideIndex(swiper?.activeIndex ?? initialSlide);
25
26
  }, [setCurrentSlideIndex, swiper, initialSlide]);
26
27
  const handlePrevClick = () => {
27
28
  slidePrev();
@@ -63,6 +64,9 @@ const ImageViewer = () => {
63
64
  const swiperProps = useMemo(() => ({
64
65
  slidesPerView: 1,
65
66
  effect: 'fade',
67
+ fadeEffect: {
68
+ crossFade: true,
69
+ },
66
70
  className: cn(styles.swiper, { [styles.hidden]: fullScreen }),
67
71
  controller: { control: swiper },
68
72
  a11y: {
@@ -83,7 +87,7 @@ const ImageViewer = () => {
83
87
  React.createElement("div", { className: cn(styles.component, { [styles.singleSlide]: singleSlide }), onClick: handleWrapperClick },
84
88
  showControls && (React.createElement("div", { className: cn(styles.arrow, {
85
89
  [styles.focused]: leftArrowFocused,
86
- }), onClick: handlePrevClick, role: 'button', onKeyDown: handleArrowLeftKeyDown, tabIndex: 0, ref: leftArrowRef, "aria-label": '\u041F\u0440\u0435\u0434\u044B\u0434\u0443\u0449\u0435\u0435 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435' },
90
+ }), onClick: handlePrevClick, role: 'button', onKeyDown: handleArrowLeftKeyDown, tabIndex: 0, ref: leftArrowRef, "aria-label": '\u041F\u0440\u0435\u0434\u044B\u0434\u0443\u0449\u0435\u0435 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435', "data-test-id": TestIds.PREV_SLIDE_BUTTON },
87
91
  React.createElement(ChevronBackHeavyMIcon, null))),
88
92
  fullScreen && (React.createElement("img", { src: currentImage?.src, alt: currentImage ? getImageAlt(currentImage, currentSlideIndex) : '', className: styles.fullScreenImage })),
89
93
  React.createElement(Swiper, Object.assign({}, swiperProps), images.map((image, index) => {
@@ -92,11 +96,14 @@ const ImageViewer = () => {
92
96
  const imageHeight = meta?.height || 1;
93
97
  const imageAspectRatio = imageWidth / imageHeight;
94
98
  const slideVisible = index === currentSlideIndex;
95
- return (React.createElement(SwiperSlide, { key: getImageKey(image, index), style: { pointerEvents: slideVisible ? 'auto' : 'none' } }, ({ isActive }) => (React.createElement(Slide, { isActive: isActive, swiperAspectRatio: swiperAspectRatio, image: image, swiperHeight: swiperHeight, meta: meta, index: index, imageAspectRatio: imageAspectRatio, handleLoad: handleLoad, handleLoadError: handleLoadError }))));
99
+ return (React.createElement(SwiperSlide, { key: getImageKey(image, index), style: {
100
+ pointerEvents: slideVisible ? 'auto' : 'none',
101
+ transitionProperty: 'opacity',
102
+ } }, ({ isActive }) => (React.createElement(Slide, { isActive: isActive, swiperAspectRatio: swiperAspectRatio, image: image, swiperHeight: swiperHeight, meta: meta, index: index, imageAspectRatio: imageAspectRatio, slideVisible: slideVisible, handleLoad: handleLoad, handleLoadError: handleLoadError }))));
96
103
  })),
97
104
  showControls && (React.createElement("div", { className: cn(styles.arrow, {
98
105
  [styles.focused]: rightArrowFocused,
99
- }), onClick: handleNextClick, role: 'button', onKeyDown: handleArrowRightKeyDown, tabIndex: 0, ref: rightArrowRef, "aria-label": '\u0421\u043B\u0435\u0434\u0443\u044E\u0449\u0435\u0435 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435' },
106
+ }), onClick: handleNextClick, role: 'button', onKeyDown: handleArrowRightKeyDown, tabIndex: 0, ref: rightArrowRef, "aria-label": '\u0421\u043B\u0435\u0434\u0443\u044E\u0449\u0435\u0435 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435', "data-test-id": TestIds.NEXT_SLIDE_BUTTON },
100
107
  React.createElement(ChevronForwardHeavyMIcon, null)))));
101
108
  };
102
109
 
@@ -1,4 +1,4 @@
1
- /* hash: hfnrp */
1
+ /* hash: 1cx9f */
2
2
  :root {
3
3
  --color-light-bg-primary: #fff;
4
4
  --color-light-border-link: #007aff;
@@ -29,14 +29,14 @@
29
29
  :root {
30
30
  --gallery-broken-image-icon: url('https://alfabank.st/icons/art_no-image_s.svg');
31
31
  }
32
- .gallery__component_hfnrp {
32
+ .gallery__component_b3ep5 {
33
33
  display: flex;
34
34
  flex-grow: 1;
35
35
  justify-content: center;
36
36
  align-items: center;
37
37
  background-color: var(--color-light-bg-primary-inverted-alpha-50);
38
38
  }
39
- .gallery__swiper_hfnrp {
39
+ .gallery__swiper_b3ep5 {
40
40
  display: flex;
41
41
  width: 100%;
42
42
  height: 100%;
@@ -46,28 +46,27 @@
46
46
  padding: var(--gap-2xl) var(--gap-m);
47
47
  box-sizing: border-box;
48
48
  }
49
- .gallery__singleSlide_hfnrp .gallery__swiper_hfnrp {
49
+ .gallery__singleSlide_b3ep5 .gallery__swiper_b3ep5 {
50
50
  max-height: calc(100vh - 80px);
51
51
  padding: var(--gap-2xl);
52
52
  }
53
- .gallery__hidden_hfnrp {
53
+ .gallery__hidden_b3ep5 {
54
54
  display: none;
55
55
  }
56
- .gallery__slide_hfnrp {
56
+ .gallery__slide_b3ep5 {
57
57
  position: relative;
58
58
  display: flex;
59
59
  justify-content: center;
60
60
  align-items: center;
61
61
  width: 100%;
62
62
  height: 100%;
63
- transition: opacity 0.15s ease-in-out;
64
63
  }
65
- .gallery__slideLoading_hfnrp {
64
+ .gallery__slideLoading_b3ep5 {
66
65
  /* TODO: цвета нет в палитре */
67
66
  background-color: #e9eaeb;
68
67
  border-radius: var(--border-radius-m);
69
68
  }
70
- .gallery__image_hfnrp {
69
+ .gallery__image_b3ep5 {
71
70
  width: 0;
72
71
  height: 0;
73
72
  -webkit-user-select: none;
@@ -75,7 +74,7 @@
75
74
  background-color: var(--color-light-bg-primary);
76
75
  border-radius: var(--border-radius-m);
77
76
  }
78
- .gallery__smallImage_hfnrp {
77
+ .gallery__smallImage_b3ep5 {
79
78
  position: relative;
80
79
  width: auto;
81
80
  height: auto;
@@ -83,15 +82,15 @@
83
82
  user-select: none;
84
83
  background-color: var(--color-light-bg-primary);
85
84
  }
86
- .gallery__verticalImageFit_hfnrp {
85
+ .gallery__verticalImageFit_b3ep5 {
87
86
  width: auto;
88
87
  height: 100%;
89
88
  }
90
- .gallery__horizontalImageFit_hfnrp {
89
+ .gallery__horizontalImageFit_b3ep5 {
91
90
  width: 100%;
92
91
  height: auto;
93
92
  }
94
- .gallery__arrow_hfnrp {
93
+ .gallery__arrow_b3ep5 {
95
94
  display: flex;
96
95
  flex-direction: column;
97
96
  justify-content: center;
@@ -104,17 +103,17 @@
104
103
  transition: background-color 0.15s ease-in-out;
105
104
  outline: none
106
105
  }
107
- .gallery__arrow_hfnrp:hover {
106
+ .gallery__arrow_b3ep5:hover {
108
107
  background-color: var(--color-light-bg-primary-inverted-alpha-10);
109
108
  }
110
- .gallery__arrow_hfnrp:active {
109
+ .gallery__arrow_b3ep5:active {
111
110
  background-color: var(--color-light-bg-primary-inverted-alpha-20);
112
111
  }
113
- .gallery__focused_hfnrp {
112
+ .gallery__focused_b3ep5 {
114
113
  outline: 2px solid var(--focus-color);
115
114
  outline-offset: 2px;
116
115
  }
117
- .gallery__placeholder_hfnrp {
116
+ .gallery__placeholder_b3ep5 {
118
117
  display: flex;
119
118
  justify-content: center;
120
119
  align-items: center;
@@ -123,7 +122,7 @@
123
122
  border-radius: var(--border-radius-m);
124
123
  background-color: var(--color-light-bg-primary);
125
124
  }
126
- .gallery__brokenImgWrapper_hfnrp {
125
+ .gallery__brokenImgWrapper_b3ep5 {
127
126
  position: relative;
128
127
  display: flex;
129
128
  flex-direction: column;
@@ -131,7 +130,7 @@
131
130
  width: 150px;
132
131
  text-align: center;
133
132
  }
134
- .gallery__brokenImgIcon_hfnrp {
133
+ .gallery__brokenImgIcon_b3ep5 {
135
134
  width: 80px;
136
135
  height: 80px;
137
136
  margin-bottom: var(--gap-2xs);
@@ -139,7 +138,7 @@
139
138
  background-size: contain;
140
139
  background-repeat: no-repeat;
141
140
  }
142
- .gallery__fullScreenImage_hfnrp {
141
+ .gallery__fullScreenImage_b3ep5 {
143
142
  width: 100%;
144
143
  height: auto;
145
144
  background-color: var(--color-light-bg-primary);
@@ -3,6 +3,7 @@ import 'classnames';
3
3
  import '@alfalab/hooks';
4
4
  import '../../context.js';
5
5
  import '../../utils/utils.js';
6
+ import '../../utils/constants.js';
6
7
  import '@alfalab/core-components-typography/dist/modern';
7
8
  import 'swiper';
8
9
  import 'swiper/react';
@@ -10,5 +11,5 @@ import 'element-closest';
10
11
  import 'swiper/swiper.min.css';
11
12
  import '@alfalab/icons-glyph/ChevronBackHeavyMIcon';
12
13
  import '@alfalab/icons-glyph/ChevronForwardHeavyMIcon';
13
- import '../../slide-db4a1a0f.js';
14
+ import '../../slide-831df2ef.js';
14
15
  export { ImageViewer } from './component.js';
@@ -1,5 +1,6 @@
1
1
  import 'react';
2
2
  import 'classnames';
3
3
  import '../../utils/utils.js';
4
+ import '../../utils/constants.js';
4
5
  import '@alfalab/core-components-typography/dist/modern';
5
- export { S as Slide } from '../../slide-db4a1a0f.js';
6
+ export { S as Slide } from '../../slide-831df2ef.js';
@@ -6,6 +6,7 @@ export { ImagePreview } from './image-preview/Component.js';
6
6
  export { NavigationBar } from './navigation-bar/Component.js';
7
7
  import '../utils/split-filename.js';
8
8
  import '../utils/utils.js';
9
+ import '../utils/constants.js';
9
10
  import '@alfalab/core-components-typography/dist/modern';
10
11
  import './header-info-block/Component.js';
11
12
  import '@alfalab/core-components-icon-button/dist/modern';
@@ -22,5 +23,5 @@ import 'element-closest';
22
23
  import 'swiper/swiper.min.css';
23
24
  import '@alfalab/icons-glyph/ChevronBackHeavyMIcon';
24
25
  import '@alfalab/icons-glyph/ChevronForwardHeavyMIcon';
25
- import '../slide-db4a1a0f.js';
26
+ import '../slide-831df2ef.js';
26
27
  export { ImageViewer } from './image-viewer/component.js';
@@ -4,8 +4,9 @@ import '@alfalab/hooks';
4
4
  import { GalleryContext } from '../../context.js';
5
5
  import { ImagePreview } from '../image-preview/Component.js';
6
6
  import { getImageKey } from '../../utils/utils.js';
7
+ import { TestIds } from '../../utils/constants.js';
7
8
 
8
- var styles = {"component":"gallery__component_pmo4k","preview":"gallery__preview_pmo4k"};
9
+ var styles = {"component":"gallery__component_svs19","preview":"gallery__preview_svs19"};
9
10
  require('./index.css')
10
11
 
11
12
  const MIN_SCROLL_STEP = 24;
@@ -55,7 +56,7 @@ const NavigationBar = () => {
55
56
  }, [currentSlideIndex, handlePreviewPosition, scroll]);
56
57
  return (
57
58
  // eslint-disable-next-line jsx-a11y/no-static-element-interactions
58
- React.createElement("div", { className: styles.component, ref: containerRef, onKeyDown: handleKeyDown }, images.map((image, index) => {
59
+ React.createElement("div", { className: styles.component, ref: containerRef, onKeyDown: handleKeyDown, "data-test-id": TestIds.NAVIGATION_BAR }, images.map((image, index) => {
59
60
  const active = index === currentSlideIndex;
60
61
  return (React.createElement(ImagePreview, { key: getImageKey(image, index), image: image, active: active, index: index, onSelect: handlePreviewSelect, className: styles.preview }));
61
62
  })));
@@ -1,4 +1,4 @@
1
- /* hash: pmo4k */
1
+ /* hash: 1t66i */
2
2
  :root {
3
3
  --color-light-bg-tertiary-inverted: #3c4c5d;
4
4
  }
@@ -14,7 +14,7 @@
14
14
  --gap-3xs: 2px;
15
15
  --gap-xl: 24px;
16
16
  }
17
- .gallery__component_pmo4k {
17
+ .gallery__component_svs19 {
18
18
  display: flex;
19
19
  flex-wrap: nowrap;
20
20
  align-content: center;
@@ -27,16 +27,16 @@
27
27
  background-color: var(--color-light-bg-tertiary-inverted);
28
28
  scrollbar-width: none
29
29
  }
30
- .gallery__component_pmo4k::-webkit-scrollbar {
30
+ .gallery__component_svs19::-webkit-scrollbar {
31
31
  display: none;
32
32
  }
33
- .gallery__preview_pmo4k {
33
+ .gallery__preview_svs19 {
34
34
  flex-shrink: 0;
35
35
  margin: 0 var(--gap-3xs)
36
36
  }
37
- .gallery__preview_pmo4k:first-child {
37
+ .gallery__preview_svs19:first-child {
38
38
  margin-left: auto;
39
39
  }
40
- .gallery__preview_pmo4k:last-child {
40
+ .gallery__preview_svs19:last-child {
41
41
  margin-right: auto;
42
42
  }
@@ -5,3 +5,4 @@ import '../../context.js';
5
5
  import '../image-preview/Component.js';
6
6
  export { NavigationBar } from './Component.js';
7
7
  import '../../utils/utils.js';
8
+ import '../../utils/constants.js';
@@ -1,4 +1,4 @@
1
- /* hash: th1rc */
1
+ /* hash: 1oynf */
2
2
  :root {
3
3
 
4
4
  /* Hard */
@@ -7,14 +7,14 @@
7
7
 
8
8
  /* Hard up */
9
9
  }
10
- .gallery__container_th1rc {
10
+ .gallery__container_1g1fk {
11
11
  display: flex;
12
12
  flex-direction: column;
13
13
  justify-content: space-between;
14
14
  height: 100%;
15
15
  width: 100%;
16
16
  }
17
- .gallery__modal_th1rc {
17
+ .gallery__modal_1g1fk {
18
18
  flex-grow: 1;
19
19
  width: 100%;
20
20
  background: transparent;
@@ -1 +1,2 @@
1
1
  export * from "./Component";
2
+ export * from "./utils/index";
@@ -5,8 +5,9 @@ import '@alfalab/hooks';
5
5
  import './context.js';
6
6
  import './components/image-preview/Component.js';
7
7
  import './components/navigation-bar/Component.js';
8
- import './utils/split-filename.js';
9
- import './utils/utils.js';
8
+ export { splitFilename } from './utils/split-filename.js';
9
+ export { PLACEHOLDER_HEIGHT, PLACEHOLDER_WIDTH, getImageAlt, getImageKey, isSmallImage } from './utils/utils.js';
10
+ export { TestIds } from './utils/constants.js';
10
11
  import '@alfalab/core-components-typography/dist/modern';
11
12
  import './components/header-info-block/Component.js';
12
13
  import '@alfalab/core-components-icon-button/dist/modern';
@@ -23,6 +24,6 @@ import 'element-closest';
23
24
  import 'swiper/swiper.min.css';
24
25
  import '@alfalab/icons-glyph/ChevronBackHeavyMIcon';
25
26
  import '@alfalab/icons-glyph/ChevronForwardHeavyMIcon';
26
- import './slide-db4a1a0f.js';
27
+ import './slide-831df2ef.js';
27
28
  import './components/image-viewer/component.js';
28
29
  export { Gallery } from './Component.js';
@@ -8,6 +8,7 @@ type SlideProps = {
8
8
  imageAspectRatio: number;
9
9
  index: number;
10
10
  swiperHeight: number;
11
+ slideVisible: boolean;
11
12
  handleLoad: (event: SyntheticEvent<HTMLImageElement>, index: number) => void;
12
13
  handleLoadError: (index: number) => void;
13
14
  };
@@ -1,12 +1,13 @@
1
1
  import React from 'react';
2
2
  import cn from 'classnames';
3
3
  import { isSmallImage, getImageAlt } from './utils/utils.js';
4
+ import { TestIds } from './utils/constants.js';
4
5
  import { Typography } from '@alfalab/core-components-typography/dist/modern';
5
6
 
6
- var styles = {"component":"gallery__component_hfnrp","swiper":"gallery__swiper_hfnrp","singleSlide":"gallery__singleSlide_hfnrp","hidden":"gallery__hidden_hfnrp","slide":"gallery__slide_hfnrp","slideLoading":"gallery__slideLoading_hfnrp","image":"gallery__image_hfnrp","smallImage":"gallery__smallImage_hfnrp","verticalImageFit":"gallery__verticalImageFit_hfnrp","horizontalImageFit":"gallery__horizontalImageFit_hfnrp","arrow":"gallery__arrow_hfnrp","focused":"gallery__focused_hfnrp","placeholder":"gallery__placeholder_hfnrp","brokenImgWrapper":"gallery__brokenImgWrapper_hfnrp","brokenImgIcon":"gallery__brokenImgIcon_hfnrp","fullScreenImage":"gallery__fullScreenImage_hfnrp"};
7
+ var styles = {"component":"gallery__component_b3ep5","swiper":"gallery__swiper_b3ep5","singleSlide":"gallery__singleSlide_b3ep5","hidden":"gallery__hidden_b3ep5","slide":"gallery__slide_b3ep5","slideLoading":"gallery__slideLoading_b3ep5","image":"gallery__image_b3ep5","smallImage":"gallery__smallImage_b3ep5","verticalImageFit":"gallery__verticalImageFit_b3ep5","horizontalImageFit":"gallery__horizontalImageFit_b3ep5","arrow":"gallery__arrow_b3ep5","focused":"gallery__focused_b3ep5","placeholder":"gallery__placeholder_b3ep5","brokenImgWrapper":"gallery__brokenImgWrapper_b3ep5","brokenImgIcon":"gallery__brokenImgIcon_b3ep5","fullScreenImage":"gallery__fullScreenImage_b3ep5"};
7
8
  require('./components/image-viewer/index.css')
8
9
 
9
- const Slide = ({ isActive, meta, swiperAspectRatio, imageAspectRatio, image, index, swiperHeight, handleLoad, handleLoadError, }) => {
10
+ const Slide = ({ isActive, meta, swiperAspectRatio, imageAspectRatio, image, index, swiperHeight, slideVisible, handleLoad, handleLoadError, }) => {
10
11
  const broken = Boolean(meta?.broken);
11
12
  const small = isSmallImage(meta);
12
13
  const verticalImageFit = !small && swiperAspectRatio > imageAspectRatio;
@@ -19,15 +20,13 @@ const Slide = ({ isActive, meta, swiperAspectRatio, imageAspectRatio, image, ind
19
20
  [styles.horizontalImageFit]: horizontalImageFit,
20
21
  }), onLoad: event => handleLoad(event, index), onError: () => handleLoadError(index), style: {
21
22
  maxHeight: `${swiperHeight}px`,
22
- } })));
23
+ }, "data-test-id": slideVisible ? TestIds.ACTIVE_IMAGE : undefined })));
23
24
  };
24
- const SlideInner = ({ children, active, broken, loading, withPlaceholder, }) => {
25
+ const SlideInner = ({ children, broken, loading, withPlaceholder }) => {
25
26
  const content = broken ? (React.createElement("div", { className: styles.brokenImgWrapper },
26
27
  React.createElement("div", { className: styles.brokenImgIcon }),
27
28
  React.createElement(Typography.Text, { view: 'primary-small', color: 'secondary' }, "\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435"))) : (children);
28
- return (React.createElement("div", { className: cn(styles.slide, { [styles.slideLoading]: loading }), style: {
29
- opacity: Number(active),
30
- } }, withPlaceholder ? React.createElement("div", { className: styles.placeholder }, content) : content));
29
+ return (React.createElement("div", { className: cn(styles.slide, { [styles.slideLoading]: loading }) }, withPlaceholder ? React.createElement("div", { className: styles.placeholder }, content) : content));
31
30
  };
32
31
 
33
32
  export { Slide as S, styles as s };
@@ -3,6 +3,7 @@ type GalleryImage = {
3
3
  name?: string;
4
4
  previewSrc?: string;
5
5
  alt?: string;
6
+ canDownload?: boolean;
6
7
  };
7
8
  type ImageMeta = {
8
9
  width: number;