CSS만으로 React에서 수평 미디어 스크롤러 구성 요소를 구현하는 방법

7983 단어 nextjsreactwebdev
모바일 해상도에서 가로로 스와이프할 수 있는 캐러셀 형식으로 목록을 렌더링하는 것이 일반적입니다. 이를 위해 간단하고 거의 JS가 없는 구성 요소를 만들었습니다. 오버플로 컨테이너를 중앙에 배치하기 위해서만 JavaScript를 사용합니다.



이를 위해 styled-components styled-breakpoints 을 사용했지만 이를 다른 CSS-in-JS 접근 방식으로 쉽게 변환할 수 있습니다.

import { Container } from 'components/Container';  
import { useEffect, useRef } from 'react';  
import { down } from 'styled-breakpoints';   
import styled from 'styled-components';  

const GridContainer = styled(Container)`  
  ${down('sm')} {  
    max-width: 100%;  
    margin: unset;  
    padding: 0;  
  }  
`;  

const Grid = styled.div<{ desktopMinWidth: string; mobileMinWidth: string }>`  
  display: grid;  
  grid-template-columns: ${({ desktopMinWidth }) => `repeat(auto-fill, minmax(${desktopMinWidth}, 1fr))`};  
  grid-gap: 18px;  

  ${down('sm')} {  
    padding: 0 20px;  
    position: relative;  

    cursor: grab;  
    scrollbar-width: none;  
    -ms-overflow-style: none;  

    ::-webkit-scrollbar {  
      width: 0px;  
      background: transparent;  
    }  

    display: flex;  
    overflow-x: auto;  
    scroll-snap-type: x mandatory;  
    -webkit-overflow-scrolling: touch;  

    & > * {  
      min-width: ${({ mobileMinWidth }) => mobileMinWidth};  
      max-width: ${({ mobileMinWidth }) => mobileMinWidth};  
      scroll-snap-align: center;  
    }  
  }  
`;  

interface SwipeableGridProps {  
  mobileMinWidth: string;  
  desktopMinWidth: string;  
  children: React.ReactNode;  
  className?: string;  
}  

export const SwipeableGrid = ({  
  mobileMinWidth,  
  desktopMinWidth,  
  children,  
  className,  
}: SwipeableGridProps) => {  
  const swipeableGridRef = useRef<HTMLDivElement | null>(null);  

  useEffect(() => {  
    const currentEl = swipeableGridRef.current;  
    if (currentEl) {  
      currentEl.scrollLeft = currentEl.clientWidth / 2;  
    }  
  }, []);  

  return (  
    <GridContainer>   
      <Grid  
        desktopMinWidth={desktopMinWidth}  
        mobileMinWidth={mobileMinWidth}  
        ref={swipeableGridRef}  
        className={className}  
      >  
        {children}  
      </Grid>  
    </GridContainer>  
  );  
};

좋은 웹페이지 즐겨찾기