@alfalab/core-components-gallery 7.1.10 → 7.2.0-alfasans
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Component.js +6 -3
- package/Component.js.map +1 -1
- package/components/bottom-button/index.css +5 -5
- package/components/bottom-button/index.module.css.js +1 -1
- package/components/buttons/index.css +5 -5
- package/components/buttons/index.module.css.js +1 -1
- package/components/header/index.css +1 -1
- package/components/header/index.module.css.js +1 -1
- package/components/header-info-block/index.css +4 -4
- package/components/header-info-block/index.module.css.js +1 -1
- package/components/header-mobile/index.css +6 -6
- package/components/header-mobile/index.module.css.js +1 -1
- package/components/image-preview/index.css +17 -17
- package/components/image-preview/index.module.css.js +1 -1
- package/components/image-viewer/component.js +30 -21
- package/components/image-viewer/component.js.map +1 -1
- package/components/image-viewer/index.css +85 -37
- package/components/image-viewer/index.module.css.js +1 -1
- package/components/image-viewer/index.module.css.js.map +1 -1
- package/components/image-viewer/single.js +2 -1
- package/components/image-viewer/single.js.map +1 -1
- package/components/image-viewer/slide.d.ts +1 -0
- package/components/image-viewer/slide.js +17 -13
- package/components/image-viewer/slide.js.map +1 -1
- package/components/image-viewer/video/index.css +13 -8
- package/components/image-viewer/video/index.module.css.js +1 -1
- package/components/image-viewer/video/index.module.css.js.map +1 -1
- package/components/info-bar/index.css +3 -3
- package/components/info-bar/index.module.css.js +1 -1
- package/components/navigation-bar/index.css +8 -8
- package/components/navigation-bar/index.module.css.js +1 -1
- package/components/subtitles/index.css +3 -3
- package/components/subtitles/index.module.css.js +1 -1
- package/cssm/Component.js +6 -3
- package/cssm/Component.js.map +1 -1
- package/cssm/components/image-viewer/component.js +30 -21
- package/cssm/components/image-viewer/component.js.map +1 -1
- package/cssm/components/image-viewer/index.module.css +66 -18
- package/cssm/components/image-viewer/single.js +2 -1
- package/cssm/components/image-viewer/single.js.map +1 -1
- package/cssm/components/image-viewer/slide.d.ts +1 -0
- package/cssm/components/image-viewer/slide.js +17 -13
- package/cssm/components/image-viewer/slide.js.map +1 -1
- package/cssm/components/image-viewer/video/index.module.css +6 -1
- package/cssm/index.module.css +2 -0
- package/esm/Component.js +6 -3
- package/esm/Component.js.map +1 -1
- package/esm/components/bottom-button/index.css +5 -5
- package/esm/components/bottom-button/index.module.css.js +1 -1
- package/esm/components/buttons/index.css +5 -5
- package/esm/components/buttons/index.module.css.js +1 -1
- package/esm/components/header/index.css +1 -1
- package/esm/components/header/index.module.css.js +1 -1
- package/esm/components/header-info-block/index.css +4 -4
- package/esm/components/header-info-block/index.module.css.js +1 -1
- package/esm/components/header-mobile/index.css +6 -6
- package/esm/components/header-mobile/index.module.css.js +1 -1
- package/esm/components/image-preview/index.css +17 -17
- package/esm/components/image-preview/index.module.css.js +1 -1
- package/esm/components/image-viewer/component.js +31 -22
- package/esm/components/image-viewer/component.js.map +1 -1
- package/esm/components/image-viewer/index.css +85 -37
- package/esm/components/image-viewer/index.module.css.js +1 -1
- package/esm/components/image-viewer/index.module.css.js.map +1 -1
- package/esm/components/image-viewer/single.js +3 -2
- package/esm/components/image-viewer/single.js.map +1 -1
- package/esm/components/image-viewer/slide.d.ts +1 -0
- package/esm/components/image-viewer/slide.js +18 -14
- package/esm/components/image-viewer/slide.js.map +1 -1
- package/esm/components/image-viewer/video/index.css +13 -8
- package/esm/components/image-viewer/video/index.module.css.js +1 -1
- package/esm/components/image-viewer/video/index.module.css.js.map +1 -1
- package/esm/components/info-bar/index.css +3 -3
- package/esm/components/info-bar/index.module.css.js +1 -1
- package/esm/components/navigation-bar/index.css +8 -8
- package/esm/components/navigation-bar/index.module.css.js +1 -1
- package/esm/components/subtitles/index.css +3 -3
- package/esm/components/subtitles/index.module.css.js +1 -1
- package/esm/index.css +11 -9
- package/esm/index.module.css.js +1 -1
- package/esm/index.module.css.js.map +1 -1
- package/index.css +11 -9
- package/index.module.css.js +1 -1
- package/index.module.css.js.map +1 -1
- package/modern/Component.js +6 -3
- package/modern/Component.js.map +1 -1
- package/modern/components/bottom-button/index.css +5 -5
- package/modern/components/bottom-button/index.module.css.js +1 -1
- package/modern/components/buttons/index.css +5 -5
- package/modern/components/buttons/index.module.css.js +1 -1
- package/modern/components/header/index.css +1 -1
- package/modern/components/header/index.module.css.js +1 -1
- package/modern/components/header-info-block/index.css +4 -4
- package/modern/components/header-info-block/index.module.css.js +1 -1
- package/modern/components/header-mobile/index.css +6 -6
- package/modern/components/header-mobile/index.module.css.js +1 -1
- package/modern/components/image-preview/index.css +17 -17
- package/modern/components/image-preview/index.module.css.js +1 -1
- package/modern/components/image-viewer/component.js +21 -13
- package/modern/components/image-viewer/component.js.map +1 -1
- package/modern/components/image-viewer/index.css +85 -37
- package/modern/components/image-viewer/index.module.css.js +1 -1
- package/modern/components/image-viewer/index.module.css.js.map +1 -1
- package/modern/components/image-viewer/single.js +3 -2
- package/modern/components/image-viewer/single.js.map +1 -1
- package/modern/components/image-viewer/slide.d.ts +1 -0
- package/modern/components/image-viewer/slide.js +11 -7
- package/modern/components/image-viewer/slide.js.map +1 -1
- package/modern/components/image-viewer/video/index.css +13 -8
- package/modern/components/image-viewer/video/index.module.css.js +1 -1
- package/modern/components/image-viewer/video/index.module.css.js.map +1 -1
- package/modern/components/info-bar/index.css +3 -3
- package/modern/components/info-bar/index.module.css.js +1 -1
- package/modern/components/navigation-bar/index.css +8 -8
- package/modern/components/navigation-bar/index.module.css.js +1 -1
- package/modern/components/subtitles/index.css +3 -3
- package/modern/components/subtitles/index.module.css.js +1 -1
- package/modern/index.css +11 -9
- package/modern/index.module.css.js +1 -1
- package/modern/index.module.css.js.map +1 -1
- package/moderncssm/Component.js +6 -3
- package/moderncssm/Component.js.map +1 -1
- package/moderncssm/components/image-viewer/component.js +21 -13
- package/moderncssm/components/image-viewer/component.js.map +1 -1
- package/moderncssm/components/image-viewer/index.module.css +65 -17
- package/moderncssm/components/image-viewer/single.js +3 -2
- package/moderncssm/components/image-viewer/single.js.map +1 -1
- package/moderncssm/components/image-viewer/slide.d.ts +1 -0
- package/moderncssm/components/image-viewer/slide.js +11 -7
- package/moderncssm/components/image-viewer/slide.js.map +1 -1
- package/moderncssm/components/image-viewer/video/index.module.css +6 -1
- package/moderncssm/index.module.css +2 -0
- package/package.json +11 -11
- package/src/Component.tsx +8 -7
- package/src/components/image-viewer/component.tsx +62 -41
- package/src/components/image-viewer/index.module.css +60 -15
- package/src/components/image-viewer/single.tsx +14 -6
- package/src/components/image-viewer/slide.tsx +24 -5
- package/src/components/image-viewer/video/index.module.css +5 -1
- package/src/index.module.css +2 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slide.js","sources":["../../../src/components/image-viewer/slide.tsx"],"sourcesContent":["import React, { type FC, type ReactNode, useContext } from 'react';\nimport cn from 'classnames';\n\nimport { Spinner } from '@alfalab/core-components-spinner';\nimport { TypographyText } from '@alfalab/core-components-typography';\n\nimport { GalleryContext } from '../../context';\nimport { type GalleryImage, type ImageMeta } from '../../types';\nimport { getImageAlt, isSmallImage, isVideo, TestIds } from '../../utils';\n\nimport { useHandleImageViewer } from './hooks';\nimport { NoImagePaths } from './paths';\nimport { Video } from './video';\n\nimport styles from './index.module.css';\n\ntype SlideInnerProps = {\n active: boolean;\n broken: boolean;\n loading: boolean;\n children: ReactNode;\n isVideoView?: boolean;\n};\n\nconst SlideInner: FC<SlideInnerProps> = ({ children, broken, loading, isVideoView }) => {\n const content = broken ? (\n <div className={styles.brokenImgWrapper}>\n <div className={styles.brokenImgIcon}>\n <svg\n xmlns='http://www.w3.org/2000/svg'\n width='80'\n height='80'\n viewBox='0 0 80 80'\n fill='none'\n >\n <rect width='80' height='80' fill='none' />\n <path\n fillRule='evenodd'\n clipRule='evenodd'\n d={NoImagePaths.baseImage}\n fill='#89898A'\n />\n <path d={NoImagePaths.triangleImage} fill='#89898A' />\n </svg>\n </div>\n\n <TypographyText view='primary-small' color='static-secondary-light'>\n Не удалось загрузить {isVideoView ? 'видео' : 'изображение'}\n </TypographyText>\n </div>\n ) : (\n children\n );\n\n return (\n <div className={cn(styles.slide, { [styles.slideLoading]: loading })}>\n {broken ? <div className={styles.placeholder}>{content}</div> : content}\n <Spinner className={styles.spinner} preset={48} visible={loading} />\n </div>\n );\n};\n\ntype SlideProps = {\n isActive: boolean;\n image: GalleryImage;\n meta?: ImageMeta;\n containerAspectRatio: number;\n imageAspectRatio: number;\n index: number;\n containerHeight: number;\n slideVisible: boolean;\n};\n\nexport const Slide: FC<SlideProps> = ({\n isActive,\n meta,\n containerAspectRatio,\n imageAspectRatio,\n image,\n index,\n containerHeight,\n slideVisible,\n}) => {\n const { view } = useContext(GalleryContext);\n const { handleLoad, handleLoadError } = useHandleImageViewer();\n\n const broken = Boolean(meta?.broken);\n const small = isSmallImage(meta);\n const verticalImageFit = !small && containerAspectRatio > imageAspectRatio;\n const horizontalImageFit = !small && containerAspectRatio <= imageAspectRatio;\n\n if (isVideo(image.src)) {\n return (\n <SlideInner isVideoView={true} active={isActive} broken={broken} loading={!meta}>\n <Video
|
|
1
|
+
{"version":3,"file":"slide.js","sources":["../../../src/components/image-viewer/slide.tsx"],"sourcesContent":["import React, { type FC, type ReactNode, useCallback, useContext } from 'react';\nimport cn from 'classnames';\n\nimport { Spinner } from '@alfalab/core-components-spinner';\nimport { TypographyText } from '@alfalab/core-components-typography';\n\nimport { GalleryContext } from '../../context';\nimport { type GalleryImage, type ImageMeta } from '../../types';\nimport { getImageAlt, isSmallImage, isVideo, TestIds } from '../../utils';\n\nimport { useHandleImageViewer } from './hooks';\nimport { NoImagePaths } from './paths';\nimport { Video } from './video';\n\nimport styles from './index.module.css';\n\ntype SlideInnerProps = {\n active: boolean;\n broken: boolean;\n loading: boolean;\n children: ReactNode;\n isVideoView?: boolean;\n};\n\nconst SlideInner: FC<SlideInnerProps> = ({ children, broken, loading, isVideoView }) => {\n const content = broken ? (\n <div className={styles.brokenImgWrapper}>\n <div className={styles.brokenImgIcon}>\n <svg\n xmlns='http://www.w3.org/2000/svg'\n width='80'\n height='80'\n viewBox='0 0 80 80'\n fill='none'\n >\n <rect width='80' height='80' fill='none' />\n <path\n fillRule='evenodd'\n clipRule='evenodd'\n d={NoImagePaths.baseImage}\n fill='#89898A'\n />\n <path d={NoImagePaths.triangleImage} fill='#89898A' />\n </svg>\n </div>\n\n <TypographyText view='primary-small' color='static-secondary-light'>\n Не удалось загрузить {isVideoView ? 'видео' : 'изображение'}\n </TypographyText>\n </div>\n ) : (\n children\n );\n\n return (\n <div className={cn(styles.slide, { [styles.slideLoading]: loading })}>\n {broken ? <div className={styles.placeholder}>{content}</div> : content}\n <Spinner className={styles.spinner} preset={48} visible={loading} />\n </div>\n );\n};\n\ntype SlideProps = {\n isActive: boolean;\n image: GalleryImage;\n meta?: ImageMeta;\n containerAspectRatio: number;\n imageAspectRatio: number;\n index: number;\n containerHeight: number;\n slideVisible: boolean;\n fullScreen?: boolean;\n};\n\nexport const Slide: FC<SlideProps> = ({\n isActive,\n meta,\n containerAspectRatio,\n imageAspectRatio,\n image,\n index,\n containerHeight,\n slideVisible,\n fullScreen,\n}) => {\n const { view } = useContext(GalleryContext);\n const { handleLoad, handleLoadError } = useHandleImageViewer();\n\n const broken = Boolean(meta?.broken);\n const small = isSmallImage(meta);\n const verticalImageFit = !small && containerAspectRatio > imageAspectRatio;\n const horizontalImageFit = !small && containerAspectRatio <= imageAspectRatio;\n\n const handleImageRef = useCallback(\n (node: HTMLImageElement | null) => {\n if (node?.complete && node.naturalWidth > 0 && !meta) {\n handleLoad(\n { currentTarget: node } as React.SyntheticEvent<HTMLImageElement>,\n index,\n );\n }\n },\n [handleLoad, index, meta],\n );\n\n if (isVideo(image.src)) {\n return (\n <SlideInner isVideoView={true} active={isActive} broken={broken} loading={!meta}>\n <Video\n url={image.src}\n index={index}\n isActive={isActive}\n className={cn({ [styles.fullScreenMedia]: fullScreen })}\n />\n </SlideInner>\n );\n }\n\n return (\n <SlideInner active={isActive} broken={broken} loading={!meta}>\n <img\n ref={handleImageRef}\n src={image.src}\n alt={getImageAlt(image, index)}\n className={cn({\n [styles.smallImage]: small,\n [styles.image]: !small && meta,\n [styles.mobile]: view === 'mobile',\n [styles.fullScreenMedia]: fullScreen,\n [styles.verticalImageFit]: verticalImageFit,\n [styles.horizontalImageFit]: horizontalImageFit,\n })}\n onLoad={(event) => handleLoad(event, index)}\n onError={() => handleLoadError(index)}\n style={fullScreen ? undefined : { maxHeight: `${containerHeight}px` }}\n data-test-id={slideVisible ? TestIds.ACTIVE_IMAGE : undefined}\n />\n </SlideInner>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -2,15 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
.videoWrapper {
|
|
4
4
|
display: flex;
|
|
5
|
+
align-items: center;
|
|
5
6
|
justify-content: center;
|
|
6
7
|
height: 100%;
|
|
7
|
-
width:
|
|
8
|
+
width: 100%;
|
|
9
|
+
min-width: 0;
|
|
10
|
+
min-height: 0;
|
|
8
11
|
position: relative;
|
|
9
12
|
}
|
|
10
13
|
|
|
11
14
|
.video {
|
|
12
15
|
max-width: 100%;
|
|
13
16
|
max-height: 100%;
|
|
17
|
+
-o-object-fit: contain;
|
|
18
|
+
object-fit: contain;
|
|
14
19
|
border-radius: var(--border-radius-24);
|
|
15
20
|
}
|
|
16
21
|
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
flex-direction: column;
|
|
12
12
|
justify-content: space-between;
|
|
13
13
|
height: 100%;
|
|
14
|
+
height: 100dvh;
|
|
14
15
|
width: 100%;
|
|
15
16
|
background-color: var(--color-static-neutral-0-inverted);
|
|
16
17
|
padding-top: var(--sat);
|
|
@@ -25,6 +26,7 @@
|
|
|
25
26
|
flex-grow: 1;
|
|
26
27
|
width: 100vw;
|
|
27
28
|
height: 100vh;
|
|
29
|
+
height: 100dvh;
|
|
28
30
|
background: transparent;
|
|
29
31
|
}
|
|
30
32
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alfalab/core-components-gallery",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.2.0-alfasans",
|
|
4
4
|
"description": "",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"license": "MIT",
|
|
@@ -13,14 +13,14 @@
|
|
|
13
13
|
"build": "rollup -c ../../tools/rollup/rollup.config.mjs --silent"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@alfalab/core-components-base-modal": "
|
|
17
|
-
"@alfalab/core-components-button": "
|
|
18
|
-
"@alfalab/core-components-icon-button": "
|
|
19
|
-
"@alfalab/core-components-icon-view": "
|
|
20
|
-
"@alfalab/core-components-mq": "
|
|
21
|
-
"@alfalab/core-components-spinner": "
|
|
22
|
-
"@alfalab/core-components-tooltip": "
|
|
23
|
-
"@alfalab/core-components-typography": "
|
|
16
|
+
"@alfalab/core-components-base-modal": "7.1.7-alfasans",
|
|
17
|
+
"@alfalab/core-components-button": "13.2.1-alfasans",
|
|
18
|
+
"@alfalab/core-components-icon-button": "8.0.9-alfasans",
|
|
19
|
+
"@alfalab/core-components-icon-view": "5.0.4-alfasans",
|
|
20
|
+
"@alfalab/core-components-mq": "6.0.6-alfasans",
|
|
21
|
+
"@alfalab/core-components-spinner": "6.0.6-alfasans",
|
|
22
|
+
"@alfalab/core-components-tooltip": "9.0.16-alfasans",
|
|
23
|
+
"@alfalab/core-components-typography": "6.0.9-alfasans",
|
|
24
24
|
"@alfalab/hooks": "^1.17.0",
|
|
25
25
|
"@alfalab/icons-glyph": "^2.260.0",
|
|
26
26
|
"classnames": "^2.5.1",
|
|
@@ -38,6 +38,6 @@
|
|
|
38
38
|
"access": "public",
|
|
39
39
|
"directory": "dist"
|
|
40
40
|
},
|
|
41
|
-
"themesVersion": "15.
|
|
42
|
-
"varsVersion": "11.1.0"
|
|
41
|
+
"themesVersion": "15.2.0-alfasans",
|
|
42
|
+
"varsVersion": "11.1.0-alfasans"
|
|
43
43
|
}
|
package/src/Component.tsx
CHANGED
|
@@ -133,14 +133,15 @@ export const Gallery: FC<GalleryProps> = ({
|
|
|
133
133
|
slideTo(nextIndex);
|
|
134
134
|
}, [images.length, loop, currentSlideIndex, slideTo]);
|
|
135
135
|
|
|
136
|
-
const setImageMeta = useCallback(
|
|
137
|
-
(
|
|
138
|
-
|
|
136
|
+
const setImageMeta = useCallback((meta: ImageMeta, index: number) => {
|
|
137
|
+
setImagesMeta((prevImagesMeta) => {
|
|
138
|
+
const nextImagesMeta = prevImagesMeta.slice();
|
|
139
139
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
140
|
+
nextImagesMeta[index] = meta;
|
|
141
|
+
|
|
142
|
+
return nextImagesMeta;
|
|
143
|
+
});
|
|
144
|
+
}, []);
|
|
144
145
|
|
|
145
146
|
const handleBottomButtonClick = useCallback(
|
|
146
147
|
(e: MouseEvent) => {
|
|
@@ -8,7 +8,7 @@ import { ChevronBackHeavyMIcon } from '@alfalab/icons-glyph/ChevronBackHeavyMIco
|
|
|
8
8
|
import { ChevronForwardHeavyMIcon } from '@alfalab/icons-glyph/ChevronForwardHeavyMIcon';
|
|
9
9
|
|
|
10
10
|
import { GalleryContext } from '../../context';
|
|
11
|
-
import {
|
|
11
|
+
import { getImageKey, isVideo, TestIds } from '../../utils';
|
|
12
12
|
|
|
13
13
|
import { useHandleImageViewer } from './hooks';
|
|
14
14
|
import { Slide } from './slide';
|
|
@@ -128,49 +128,70 @@ export const ImageViewer: FC = () => {
|
|
|
128
128
|
</div>
|
|
129
129
|
)}
|
|
130
130
|
|
|
131
|
-
{fullScreen && !isVideo(currentImage
|
|
132
|
-
<
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
131
|
+
{fullScreen && currentImage && !isVideo(currentImage.src) && (
|
|
132
|
+
<div className={styles.fullScreenFrame}>
|
|
133
|
+
<Slide
|
|
134
|
+
isActive={true}
|
|
135
|
+
containerAspectRatio={swiperAspectRatio}
|
|
136
|
+
image={currentImage}
|
|
137
|
+
containerHeight={swiperHeight}
|
|
138
|
+
meta={imagesMeta[currentSlideIndex]}
|
|
139
|
+
index={currentSlideIndex}
|
|
140
|
+
imageAspectRatio={
|
|
141
|
+
(imagesMeta[currentSlideIndex]?.width || 1) /
|
|
142
|
+
(imagesMeta[currentSlideIndex]?.height || 1)
|
|
143
|
+
}
|
|
144
|
+
slideVisible={false}
|
|
145
|
+
fullScreen={true}
|
|
146
|
+
/>
|
|
147
|
+
</div>
|
|
137
148
|
)}
|
|
138
149
|
|
|
139
|
-
<
|
|
140
|
-
{
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
const imageAspectRatio = imageWidth / imageHeight;
|
|
147
|
-
|
|
148
|
-
const slideVisible = index === currentSlideIndex;
|
|
149
|
-
|
|
150
|
-
return (
|
|
151
|
-
<SwiperSlide
|
|
152
|
-
key={getImageKey(image, index)}
|
|
153
|
-
style={{
|
|
154
|
-
pointerEvents: slideVisible ? 'auto' : 'none',
|
|
155
|
-
transitionProperty: 'opacity',
|
|
156
|
-
}}
|
|
157
|
-
>
|
|
158
|
-
{({ isActive }) => (
|
|
159
|
-
<Slide
|
|
160
|
-
isActive={isActive}
|
|
161
|
-
containerAspectRatio={swiperAspectRatio}
|
|
162
|
-
image={image}
|
|
163
|
-
containerHeight={swiperHeight}
|
|
164
|
-
meta={meta}
|
|
165
|
-
index={index}
|
|
166
|
-
imageAspectRatio={imageAspectRatio}
|
|
167
|
-
slideVisible={slideVisible}
|
|
168
|
-
/>
|
|
169
|
-
)}
|
|
170
|
-
</SwiperSlide>
|
|
171
|
-
);
|
|
150
|
+
<div
|
|
151
|
+
className={cn(styles.swiperFrame, {
|
|
152
|
+
[styles.mobile]: isMobile,
|
|
153
|
+
[styles.mobileVideo]: isMobile && isVideo(currentImage?.src),
|
|
154
|
+
[styles.fullScreenFrame]: fullScreen,
|
|
155
|
+
[styles.hiddenFrame]: fullScreen && !isVideo(currentImage?.src),
|
|
172
156
|
})}
|
|
173
|
-
|
|
157
|
+
>
|
|
158
|
+
<Swiper {...swiperProps}>
|
|
159
|
+
{images.map((image, index) => {
|
|
160
|
+
const meta = imagesMeta[index];
|
|
161
|
+
|
|
162
|
+
const imageWidth = meta?.width || 1;
|
|
163
|
+
const imageHeight = meta?.height || 1;
|
|
164
|
+
|
|
165
|
+
const imageAspectRatio = imageWidth / imageHeight;
|
|
166
|
+
|
|
167
|
+
const slideVisible = index === currentSlideIndex;
|
|
168
|
+
|
|
169
|
+
return (
|
|
170
|
+
<SwiperSlide
|
|
171
|
+
key={getImageKey(image, index)}
|
|
172
|
+
style={{
|
|
173
|
+
pointerEvents: slideVisible ? 'auto' : 'none',
|
|
174
|
+
transitionProperty: 'opacity',
|
|
175
|
+
}}
|
|
176
|
+
>
|
|
177
|
+
{({ isActive }) => (
|
|
178
|
+
<Slide
|
|
179
|
+
isActive={isActive}
|
|
180
|
+
containerAspectRatio={swiperAspectRatio}
|
|
181
|
+
image={image}
|
|
182
|
+
containerHeight={swiperHeight}
|
|
183
|
+
meta={meta}
|
|
184
|
+
index={index}
|
|
185
|
+
imageAspectRatio={imageAspectRatio}
|
|
186
|
+
slideVisible={slideVisible}
|
|
187
|
+
fullScreen={fullScreen && isVideo(image.src)}
|
|
188
|
+
/>
|
|
189
|
+
)}
|
|
190
|
+
</SwiperSlide>
|
|
191
|
+
);
|
|
192
|
+
})}
|
|
193
|
+
</Swiper>
|
|
194
|
+
</div>
|
|
174
195
|
|
|
175
196
|
{showControls && (
|
|
176
197
|
<div
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
display: flex;
|
|
5
5
|
flex-grow: 1;
|
|
6
6
|
justify-content: center;
|
|
7
|
+
min-height: 0;
|
|
7
8
|
background-color: var(--color-static-neutral-0-inverted);
|
|
8
9
|
|
|
9
10
|
/* swiper/swiper.css; */
|
|
@@ -69,48 +70,82 @@
|
|
|
69
70
|
z-index: -1000;
|
|
70
71
|
}
|
|
71
72
|
|
|
72
|
-
.
|
|
73
|
+
.swiperFrame {
|
|
73
74
|
display: flex;
|
|
74
75
|
width: 100%;
|
|
75
76
|
height: 100%;
|
|
77
|
+
min-height: 0;
|
|
76
78
|
|
|
77
79
|
/* 168px - высота хэдера и футера */
|
|
78
80
|
max-height: calc(100vh - 168px);
|
|
81
|
+
max-height: calc(100dvh - 168px);
|
|
79
82
|
padding: var(--gap-32) var(--gap-16);
|
|
80
83
|
box-sizing: border-box;
|
|
81
84
|
|
|
82
85
|
&.mobile {
|
|
83
86
|
max-height: calc(100vh - 210px);
|
|
87
|
+
max-height: calc(100dvh - 210px);
|
|
84
88
|
}
|
|
85
89
|
|
|
86
90
|
&.mobileVideo {
|
|
87
91
|
max-height: 100vh;
|
|
92
|
+
max-height: 100dvh;
|
|
88
93
|
}
|
|
89
94
|
}
|
|
90
95
|
|
|
96
|
+
.fullScreenFrame {
|
|
97
|
+
display: flex;
|
|
98
|
+
align-items: center;
|
|
99
|
+
justify-content: center;
|
|
100
|
+
width: 100%;
|
|
101
|
+
height: 100%;
|
|
102
|
+
max-height: none;
|
|
103
|
+
min-height: 0;
|
|
104
|
+
padding: var(--gap-0);
|
|
105
|
+
box-sizing: border-box;
|
|
106
|
+
overflow: hidden;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.hiddenFrame {
|
|
110
|
+
flex: 0 0 0;
|
|
111
|
+
width: 0;
|
|
112
|
+
height: 0;
|
|
113
|
+
padding: var(--gap-0);
|
|
114
|
+
overflow: hidden;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.swiper {
|
|
118
|
+
width: 100%;
|
|
119
|
+
height: 100%;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.hidden {
|
|
123
|
+
display: none;
|
|
124
|
+
}
|
|
125
|
+
|
|
91
126
|
.singleSlideContainer {
|
|
92
127
|
display: flex;
|
|
93
128
|
width: 100%;
|
|
94
129
|
height: 100%;
|
|
130
|
+
min-height: 0;
|
|
95
131
|
|
|
96
132
|
max-height: calc(100vh - 80px);
|
|
133
|
+
max-height: calc(100dvh - 80px);
|
|
97
134
|
padding: var(--gap-32);
|
|
98
135
|
box-sizing: border-box;
|
|
99
136
|
|
|
100
137
|
&.mobile {
|
|
101
138
|
max-height: calc(100vh - 174px);
|
|
139
|
+
max-height: calc(100dvh - 174px);
|
|
102
140
|
padding: 0;
|
|
103
141
|
}
|
|
104
142
|
|
|
105
143
|
&.mobileVideo {
|
|
106
144
|
max-height: 100vh;
|
|
145
|
+
max-height: 100dvh;
|
|
107
146
|
}
|
|
108
147
|
}
|
|
109
148
|
|
|
110
|
-
.hidden {
|
|
111
|
-
display: none;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
149
|
.slide {
|
|
115
150
|
position: relative;
|
|
116
151
|
display: flex;
|
|
@@ -131,8 +166,11 @@
|
|
|
131
166
|
}
|
|
132
167
|
|
|
133
168
|
.image {
|
|
134
|
-
width:
|
|
135
|
-
height:
|
|
169
|
+
width: auto;
|
|
170
|
+
height: auto;
|
|
171
|
+
max-width: 100%;
|
|
172
|
+
max-height: 100%;
|
|
173
|
+
object-fit: contain;
|
|
136
174
|
user-select: none;
|
|
137
175
|
border-radius: var(--border-radius-8);
|
|
138
176
|
|
|
@@ -145,6 +183,9 @@
|
|
|
145
183
|
position: relative;
|
|
146
184
|
width: auto;
|
|
147
185
|
height: auto;
|
|
186
|
+
max-width: 100%;
|
|
187
|
+
max-height: 100%;
|
|
188
|
+
object-fit: contain;
|
|
148
189
|
user-select: none;
|
|
149
190
|
}
|
|
150
191
|
|
|
@@ -158,6 +199,15 @@
|
|
|
158
199
|
height: auto;
|
|
159
200
|
}
|
|
160
201
|
|
|
202
|
+
.fullScreenMedia {
|
|
203
|
+
width: 100%;
|
|
204
|
+
height: 100%;
|
|
205
|
+
max-width: 100%;
|
|
206
|
+
max-height: 100%;
|
|
207
|
+
object-fit: contain;
|
|
208
|
+
border-radius: var(--border-radius-0);
|
|
209
|
+
}
|
|
210
|
+
|
|
161
211
|
.arrow {
|
|
162
212
|
display: flex;
|
|
163
213
|
flex-direction: column;
|
|
@@ -209,14 +259,9 @@
|
|
|
209
259
|
margin-bottom: var(--gap-4);
|
|
210
260
|
}
|
|
211
261
|
|
|
212
|
-
.fullScreenImage {
|
|
213
|
-
width: 100%;
|
|
214
|
-
height: auto;
|
|
215
|
-
background-color: var(--color-light-base-bg-primary);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
262
|
.fullScreenVideo {
|
|
219
|
-
width:
|
|
220
|
-
|
|
263
|
+
width: 100%;
|
|
264
|
+
height: 100%;
|
|
265
|
+
max-height: none;
|
|
221
266
|
}
|
|
222
267
|
}
|
|
@@ -2,7 +2,7 @@ import React, { type FC, useContext, useRef } from 'react';
|
|
|
2
2
|
import cn from 'classnames';
|
|
3
3
|
|
|
4
4
|
import { GalleryContext } from '../../context';
|
|
5
|
-
import {
|
|
5
|
+
import { isVideo } from '../../utils';
|
|
6
6
|
|
|
7
7
|
import { useHandleImageViewer } from './hooks';
|
|
8
8
|
import { Slide } from './slide';
|
|
@@ -35,11 +35,19 @@ export const Single: FC = () => {
|
|
|
35
35
|
/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */
|
|
36
36
|
<div className={styles.component} onClick={handleWrapperClick}>
|
|
37
37
|
{fullScreen && !isVideo(currentImage?.src) ? (
|
|
38
|
-
<
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
<div className={styles.fullScreenFrame}>
|
|
39
|
+
<Slide
|
|
40
|
+
isActive={true}
|
|
41
|
+
containerAspectRatio={wrapperAspectRatio}
|
|
42
|
+
image={currentImage}
|
|
43
|
+
containerHeight={wrapperRect?.height || 0}
|
|
44
|
+
meta={currentImageMeta}
|
|
45
|
+
index={currentSlideIndex}
|
|
46
|
+
imageAspectRatio={imageAspectRatio}
|
|
47
|
+
slideVisible={false}
|
|
48
|
+
fullScreen={true}
|
|
49
|
+
/>
|
|
50
|
+
</div>
|
|
43
51
|
) : (
|
|
44
52
|
<div
|
|
45
53
|
className={cn(styles.singleSlideContainer, {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { type FC, type ReactNode, useContext } from 'react';
|
|
1
|
+
import React, { type FC, type ReactNode, useCallback, useContext } from 'react';
|
|
2
2
|
import cn from 'classnames';
|
|
3
3
|
|
|
4
4
|
import { Spinner } from '@alfalab/core-components-spinner';
|
|
@@ -69,6 +69,7 @@ type SlideProps = {
|
|
|
69
69
|
index: number;
|
|
70
70
|
containerHeight: number;
|
|
71
71
|
slideVisible: boolean;
|
|
72
|
+
fullScreen?: boolean;
|
|
72
73
|
};
|
|
73
74
|
|
|
74
75
|
export const Slide: FC<SlideProps> = ({
|
|
@@ -80,6 +81,7 @@ export const Slide: FC<SlideProps> = ({
|
|
|
80
81
|
index,
|
|
81
82
|
containerHeight,
|
|
82
83
|
slideVisible,
|
|
84
|
+
fullScreen,
|
|
83
85
|
}) => {
|
|
84
86
|
const { view } = useContext(GalleryContext);
|
|
85
87
|
const { handleLoad, handleLoadError } = useHandleImageViewer();
|
|
@@ -89,10 +91,27 @@ export const Slide: FC<SlideProps> = ({
|
|
|
89
91
|
const verticalImageFit = !small && containerAspectRatio > imageAspectRatio;
|
|
90
92
|
const horizontalImageFit = !small && containerAspectRatio <= imageAspectRatio;
|
|
91
93
|
|
|
94
|
+
const handleImageRef = useCallback(
|
|
95
|
+
(node: HTMLImageElement | null) => {
|
|
96
|
+
if (node?.complete && node.naturalWidth > 0 && !meta) {
|
|
97
|
+
handleLoad(
|
|
98
|
+
{ currentTarget: node } as React.SyntheticEvent<HTMLImageElement>,
|
|
99
|
+
index,
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
[handleLoad, index, meta],
|
|
104
|
+
);
|
|
105
|
+
|
|
92
106
|
if (isVideo(image.src)) {
|
|
93
107
|
return (
|
|
94
108
|
<SlideInner isVideoView={true} active={isActive} broken={broken} loading={!meta}>
|
|
95
|
-
<Video
|
|
109
|
+
<Video
|
|
110
|
+
url={image.src}
|
|
111
|
+
index={index}
|
|
112
|
+
isActive={isActive}
|
|
113
|
+
className={cn({ [styles.fullScreenMedia]: fullScreen })}
|
|
114
|
+
/>
|
|
96
115
|
</SlideInner>
|
|
97
116
|
);
|
|
98
117
|
}
|
|
@@ -100,20 +119,20 @@ export const Slide: FC<SlideProps> = ({
|
|
|
100
119
|
return (
|
|
101
120
|
<SlideInner active={isActive} broken={broken} loading={!meta}>
|
|
102
121
|
<img
|
|
122
|
+
ref={handleImageRef}
|
|
103
123
|
src={image.src}
|
|
104
124
|
alt={getImageAlt(image, index)}
|
|
105
125
|
className={cn({
|
|
106
126
|
[styles.smallImage]: small,
|
|
107
127
|
[styles.image]: !small && meta,
|
|
108
128
|
[styles.mobile]: view === 'mobile',
|
|
129
|
+
[styles.fullScreenMedia]: fullScreen,
|
|
109
130
|
[styles.verticalImageFit]: verticalImageFit,
|
|
110
131
|
[styles.horizontalImageFit]: horizontalImageFit,
|
|
111
132
|
})}
|
|
112
133
|
onLoad={(event) => handleLoad(event, index)}
|
|
113
134
|
onError={() => handleLoadError(index)}
|
|
114
|
-
style={{
|
|
115
|
-
maxHeight: `${containerHeight}px`,
|
|
116
|
-
}}
|
|
135
|
+
style={fullScreen ? undefined : { maxHeight: `${containerHeight}px` }}
|
|
117
136
|
data-test-id={slideVisible ? TestIds.ACTIVE_IMAGE : undefined}
|
|
118
137
|
/>
|
|
119
138
|
</SlideInner>
|
|
@@ -2,15 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
.videoWrapper {
|
|
4
4
|
display: flex;
|
|
5
|
+
align-items: center;
|
|
5
6
|
justify-content: center;
|
|
6
7
|
height: 100%;
|
|
7
|
-
width:
|
|
8
|
+
width: 100%;
|
|
9
|
+
min-width: 0;
|
|
10
|
+
min-height: 0;
|
|
8
11
|
position: relative;
|
|
9
12
|
}
|
|
10
13
|
|
|
11
14
|
.video {
|
|
12
15
|
max-width: 100%;
|
|
13
16
|
max-height: 100%;
|
|
17
|
+
object-fit: contain;
|
|
14
18
|
border-radius: var(--border-radius-24);
|
|
15
19
|
}
|
|
16
20
|
|
package/src/index.module.css
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
flex-direction: column;
|
|
10
10
|
justify-content: space-between;
|
|
11
11
|
height: 100%;
|
|
12
|
+
height: 100dvh;
|
|
12
13
|
width: 100%;
|
|
13
14
|
background-color: var(--color-static-neutral-0-inverted);
|
|
14
15
|
padding-top: var(--sat);
|
|
@@ -23,6 +24,7 @@
|
|
|
23
24
|
flex-grow: 1;
|
|
24
25
|
width: 100vw;
|
|
25
26
|
height: 100vh;
|
|
27
|
+
height: 100dvh;
|
|
26
28
|
background: transparent;
|
|
27
29
|
}
|
|
28
30
|
|