diff --git a/packages/media-loader/docs/assets/medialoader-carousel.mp4 b/packages/media-loader/docs/assets/medialoader-carousel.mp4 new file mode 100644 index 0000000..4aa3be9 Binary files /dev/null and b/packages/media-loader/docs/assets/medialoader-carousel.mp4 differ diff --git a/packages/media-loader/docs/assets/origin-carousel.mp4 b/packages/media-loader/docs/assets/origin-carousel.mp4 new file mode 100644 index 0000000..7676513 Binary files /dev/null and b/packages/media-loader/docs/assets/origin-carousel.mp4 differ diff --git a/packages/media-loader/src/MediaLoader/index.stories.scss b/packages/media-loader/src/MediaLoader/index.stories.scss index 0181ac7..5d41076 100644 --- a/packages/media-loader/src/MediaLoader/index.stories.scss +++ b/packages/media-loader/src/MediaLoader/index.stories.scss @@ -108,4 +108,12 @@ audio { img { border: none; } +} + +.carousel { + height: 400px; + + .slide img { + height: 400px; + } } \ No newline at end of file diff --git a/packages/media-loader/src/MediaLoader/index.stories.tsx b/packages/media-loader/src/MediaLoader/index.stories.tsx index f094ec1..3c614b6 100644 --- a/packages/media-loader/src/MediaLoader/index.stories.tsx +++ b/packages/media-loader/src/MediaLoader/index.stories.tsx @@ -7,6 +7,8 @@ import React from 'react'; import type {Meta, StoryObj} from '@storybook/react'; +import 'react-responsive-carousel/lib/styles/carousel.min.css'; // requires a loader +import {Carousel} from 'react-responsive-carousel'; import './index.stories.scss'; import MediaLoader from '../..'; @@ -429,3 +431,92 @@ export const ImagesGrid: Story = { ), }; + +export const ImagesCarousel: Story = { + name: 'Images carousel', + parameters: {}, + render: () => { + return ( +
+
+

Images carousel

+ {/*

+ This example uses the Carousel from the `react-responsive-carousel` library. By default, this + Carousel loads all the media that it is nested in it, but by adding the MediaLoader Component + the images are loading only when they are needed, that is - only when you navigate to them. +

*/} +
+
+ { + const sliderElement = document.querySelector('.slider.animated') as HTMLElement; + let imageIndexToLoad = getImageIndexFromTransformStyle(sliderElement.style.transform); + + function getImageIndexFromTransformStyle(transformStyle: string) { + let imageIndexToLoad = 0; + if (transformStyle) { + const match = transformStyle.match(/-?[\d.]+(?:%|px)/); + if (match) { + const transformPercent = match[0]; + imageIndexToLoad = parseInt(transformPercent) / -100; + } + } + return imageIndexToLoad; + } + + function loadImageByIndex(index: number) { + let imageRefToLoad = mediaHTMLElementRefs[index]; + if (imageRefToLoad && imageRefToLoad.current) { + loadMedia(imageRefToLoad.current); + } + } + + const callback = (mutationList) => { + for (const mutation of mutationList) { + if (mutation.attributeName === 'style') { + const style = mutation.target.style; + imageIndexToLoad = getImageIndexFromTransformStyle(style.transform); + loadImageByIndex(imageIndexToLoad); + break; + } + } + }; + + const observer = new MutationObserver(callback); + observer.observe(sliderElement, {attributes: true}); + + loadImageByIndex(imageIndexToLoad); + }} + > + +
+ +

Legend 1

+
+
+ +

Legend 2

+
+
+ +

Legend 3

+
+
+ +

Legend 4

+
+
+ +

Legend 5

+
+
+ +

Legend 6

+
+
+
+
+
+ ); + }, +};