유용한 패키지를 만들어서 npm에 배포하고 전세계적인 스타가 되는 상상을 전부터 하고 있었는데 이미 세상에는 유용하고 잘 만들어진 패키지가 많고 내 실력은 아직 그에 못미치기 때문에 아직 꿈을 실현하지 못했다.
물론 내 상상처럼 내가 올린 패키지를 누군가가 유용하게 사용해준다면 좋기는 하겠지만, 그게 아니어도 패키지 배포 경험을 한 번 쯤은 해보는게 좋을 것 같아서 이번에 간단하게 패키지를 하나 배포해보게 되었다.
패키지의 이름은 위와 같다. 리액트 컴포넌트 형태로 간단하게 반응형의 슬라이드를 구현할 수 있도록 만들었다. 아래 링크에서 간단하게 슬라이드를 테스트해 볼 수 있다.
https://react-responsive-slide.vercel.app/
설명은 또 작성하기 귀찮아서 npm에 등록한 리드미 내용을 그대로 들고왔다.
npm 페이지
npm i react-responsive-slide
커스텀은 크게 안되지만 나름 간단하게 컴포넌트로 생성할 수 있는 반응형 슬라이더입니다.
여기서 말하는 반응형은 한 페이지당 표시되는 슬라이드 아이템 수가 컨테이너의 사이즈에 따라 가변함을 의미합니다.
드래그도 됩니다. 멋지죠?
<Slide>
컴포넌트를 불러옵니다.import Slide from "react-responsive-slide";
function App() {
return <Slide></Slide>;
}
<Slide>
를 부모 요소(컨테이너)로 감싸고 그 레퍼런스를 생성해 <Slide>
컴포넌트의 Prop으로 전달합니다.import { useRef } from "react";
import Slide from "react-responsive-slide";
function App() {
const containerRef = useRef<HTMLDivElement>(null);
return (
<div ref={containerRef}>
<Slide slideContainer={containerRef}></Slide>
</div>
);
}
<Slide>
컴포넌트의 자식으로 슬라이드 아이템들을 넣어주면 구현 완료입니다.<Slide>
의 prop으로 슬라이드를 커스텀하거나 컨테이너와 아이템의 스타일을 선언하여 원하는대로 꾸며보세요.import { useRef } from "react";
import Slide from "react-responsive-slide";
function App() {
const containerRef = useRef<HTMLDivElement>(null);
return (
<div
ref={containerRef}
style={{ maxWidth: "90vw", backgroundColor: "blue" }}
>
<Slide slideContainer={containerRef}>
<div style={{ height: "100px", color: "red" }}>1번 슬라이드</div>
<div>2번 슬라이드</div>
<div>3번 슬라이드</div>
<div>4번 슬라이드</div>
<div>5번 슬라이드</div>
<div>6번 슬라이드</div>
</Slide>
</div>
);
}
구체적이고 다양하지는 않지만 어느정도 쓸만한 커스텀 기능을 갖고 있습니다.
다양한 파라미터를 <Slide>
컴포넌트에 전달하여 슬라이드를 커스텀할 수 있습니다.
특히 itemRatio
의 기본값은 auto
지만 다양한 반응형 환경에서 아이템이 자연스러운 사이즈를 유지할 수 있도록 적당한 값을 적용하는 것이 좋습니다.
responsives
컨테이너의 사이즈에 맞춰 페이지당 슬라이드 아이템의 개수를 설정할 수 있습니다.
따로 설정하지 않아도 반응형이 작동하지만 사이즈에 따른 개수를 직접 지정하고 싶은 경우 사용할 수 있습니다.
responsives={[
{ range: { from: null, to: 500 }, itemsPerPage: 1 },
{ range: { from: 501, to: 900 }, itemsPerPage: 3 },
{ range: { from: 901, to: 1300 }, itemsPerPage: 4 },
{ range: { from: 1301, to: null }, itemsPerPage: 5 },
]}
defaultItemsPerPage
기본값으로 사용할 페이지당 슬라이드 아이템 개수입니다.
컨테이너의 사이즈가 responsives
로 전달한 범위 어디에도 속하지 않을 경우와 초기값으로 사용됩니다.
기본값은 2
입니다.
defaultItemsPerPage={2}
itemPaddingX
슬라이드 아이템 사이의 간격입니다. 단위는 px입니다.
기본값은 12
입니다.
itemRatio
슬라이드 아이템의 가로세로 비율입니다. css aspect-ratio의 값을 사용됩니다.
기본값은 auto
입니다.
itemRatio = "4/3";
alignItems
아이템들의 세로 정렬 기준입니다. 아이템들의 높이가 다를 때 컨테이너보다 높이가 작은 아이템의 정렬 위치를 정할 수 있습니다. 유효값은 "center" | "start" | "end"
입니다.
기본값은 center
입니다.
alignItems = "center";
containerPaddingX
슬라이드 컨테이너의 좌우 여백입니다. 단위는 px입니다.
기본값은 55
입니다.
containerPaddingX={55}
containerPaddingY
슬라이드 컨테이너의 상하 여백입니다. 단위는 px입니다.
기본값은 20
입니다.
containerPaddingY={20}
autoSlide
슬라이드가 자동으로 움직일지 여부를 결정합니다.
기본값은 false
입니다.
autoSlide={12}
autoSlideInterval
슬라이드가 자동으로 움직이는 시간 간격을 결정합니다. 단위는 ms입니다.
기본값은 3000
입니다.
autoSlideInterval={3000}
draggable
터치와 드래그로 슬라이드를 이동할 수 있는지 여부를 결정합니다.
기본값은 true
입니다.
draggable={true}
color
테마 색상입니다. 네비게이션과 페이지네이션의 색상을 결정합니다. css가 이해할 수 있는 모든 색상값을 지원합니다.
기본값은 gray
입니다.
color = "gray";
navSize
네비게이션 버튼의 크기를 조절합니다. 단위는 px입니다.
기본값은 40
입니다.
navSize={40};
navBackground
네비게이션 버튼의 배경 색상을 설정합니다. css Background 값으로 사용됩니다. none
으로 배경을 없앨 수 있습니다.
기본값은 none
입니다.
navBackground = "white";
pagination
페이지네이션을 표시할지 여부를 결정합니다.
기본값은 true
입니다.
pagination={true};
clickablePagination
페이지네이션을 클릭하여 페이지를 이동할 수 있는지를 결정합니다.
기본값은 true
입니다.
clickablePagination={true};
컨테이너가 슬라이드의 반응형 기준이 되기 때문에 컨테이너가 항상 적절한 너비를 유지할 수 있도록 신경써 주세요.
import React, { useRef } from "react";
import Slide from "react-responsive-slide";
function App() {
const containerRef = useRef<HTMLDivElement>(null);
return (
<div className="App">
<div
ref={containerRef}
style={{
width: "90vw",
margin: "auto",
maxWidth: "1500px",
minWidth: "350px",
}}
>
<Slide
slideContainer={containerRef}
responsives={[
{ range: { from: null, to: 500 }, itemsPerPage: 1 },
{ range: { from: 501, to: 900 }, itemsPerPage: 3 },
{ range: { from: 901, to: 1300 }, itemsPerPage: 4 },
{ range: { from: 1301, to: null }, itemsPerPage: 5 },
]}
defaultItemsPerPage={2}
itemPaddingX={20}
itemRatio="4/3"
alignItems="center"
containerPaddingX={55}
containerPaddingY={50}
autoSlide={true}
autoSlideInterval={3000}
draggable={true}
color="deepskyblue"
navSize={50}
navBackground="none"
navOpacity={1}
pagination={true}
clickablePagination={true}
>
<div style={{ height: "100px", backgroundColor: "red" }}>0</div>
<div style={{ height: "100px", backgroundColor: "red" }}>1</div>
<div style={{ height: "100px", backgroundColor: "red" }}>2</div>
<div style={{ height: "100px", backgroundColor: "red" }}>3</div>
<div style={{ height: "100px", backgroundColor: "red" }}>4</div>
<div style={{ height: "100px", backgroundColor: "red" }}>6</div>
<div style={{ height: "100px", backgroundColor: "red" }}>7</div>
<div style={{ height: "100px", backgroundColor: "red" }}>8</div>
<div style={{ height: "100px", backgroundColor: "red" }}>9</div>
</Slide>
</div>
</div>
);
}
export default App;
이 패키지의 코드는 얼마 전 진행했던 개인 프로젝트에서 구현한 슬라이드를 기반으로 하였다. 위 링크에 대충 어떤 방식으로 슬라이드를 구현했는지 간단하게 작성해 둔 내용이 있다.
npm에 배포해보는 경험에 중점을 두고 시작한 것이기 때문에 코드 작성의 시간을 절약하기 위해 지금껏 구현한 기능 중 패키지로 만들어서 npm에 올려두면 나중에 또 써먹을만한 기능으로 적당히 골라보았다.
패키지를 최대한 가볍게 만들기 위해 기존 코드에 사용했던 tailwind css 대신 module css를 사용하려 했는데, 이렇게 되면 번들링에서 또 귀찮아질 것 같아서 평소 거의 사용하지 않는 styled-components로 리팩토링하였다.
이미 짜여진 코드를 바탕으로 개선한 것이기 때문에 어느 정도 시간은 단축했으나 한 프로젝트에서만 사용할 기능을 만드는 것에 비해 여러 프로젝트에 사용될 패키지를 만드는 것은 다양한 경우의 수와 커스텀을 염두에 두고 만들어야 하기 때문에 생각보다 추가할 내용이 많았다.
패키지 만드는 것도 보통의 기능 구현과 비슷할 줄 알았는데 직접 얕게나마 경험해보니 제대로 만들려면 난이도가 상당히 올라갈 것으로 보인다. 앞으로는 패키지 설치할 때 개발자분들에게 감사하는 마음을 갖도록 해야겠다.