All files / src/stories IntersectionObserver.stories.tsx

0% Statements 0/22
0% Branches 0/8
0% Functions 0/8
0% Lines 0/21

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87                                                                                                                                                                             
import React, { type JSX, useState } from 'react';
import { InView } from 'react-intersection-observer';
 
import { Snackbar, Typography } from '@mui/material';
import { StoryFn } from '@storybook/react';
 
import PhotosCarousel from '../components/PhotosCarousel';
 
export default {
  title: 'IntersectionObserver',
};
 
type InViewDemoProps = {
  numberOfCarousels: number;
  imagesPerCarousel: number;
};
 
const Template: StoryFn<InViewDemoProps> = (args): JSX.Element => {
  const { numberOfCarousels, imagesPerCarousel } = args;
  const carousels = [...new Array(numberOfCarousels)];
  const [visibleCarousels, setVisibleCarousels] = useState<number[]>([]);
 
  const setCarouselVisible = (index: number) => {
    if (!visibleCarousels.includes(index)) {
      setVisibleCarousels([...visibleCarousels, index]);
    }
  };
 
  const setCarouselNotVisible = (index: number) => {
    if (visibleCarousels.includes(index)) {
      setVisibleCarousels(visibleCarousels.filter((value: number) => value !== index));
    }
  };
 
  return (
    <>
      <Typography variant={'body1'} sx={{ marginBottom: '100px' }}>
        This story aims to show the NPM package `react-intersection-observer` in action, and shows how you might
        implement it in our React frontend. Use the `InView` component to easily show or hide the contents based on
        whether or not the children are in the browser's viewport. This is especially helpful when rendering very tall
        pages with expensive component hierarchies.
      </Typography>
      <Snackbar open={true}>
        <div>
          <Typography>{`Number of carousels ${numberOfCarousels}.`}</Typography>
          <Typography>{`Number of carousels rendered ${visibleCarousels.length}.`}</Typography>
        </div>
      </Snackbar>
 
      <div>
        {carousels.map((value, index) => (
          <InView key={index}>
            {({ inView, ref }) => {
              const photos = [...new Array(imagesPerCarousel)].map(
                (_value, _index) => `https://loremflickr.com/800/600/forest,jungle?lock=${_index}`
              );
 
              if (inView) {
                setCarouselVisible(index);
              } else {
                setCarouselNotVisible(index);
              }
 
              return (
                <div ref={ref}>
                  {inView ? (
                    <div style={{ minHeight: '600px' }}>
                      <PhotosCarousel photos={photos.map((url) => ({ url, alt: url }))} showArrows dots={false} />
                    </div>
                  ) : null}
                </div>
              );
            }}
          </InView>
        ))}
      </div>
    </>
  );
};
 
export const Default = Template.bind({});
 
Default.args = {
  numberOfCarousels: 10,
  imagesPerCarousel: 3,
};