[프로젝트] Icon, Image 공통 컴포넌트 회고

JUN·2024년 6월 1일

WDYTA

목록 보기
1/5

이번 팀 프로젝트를 진행하면서 1주차에는 공통 컴포넌트 구현을 목표로 잡았다. 그 중에 나는 Icon과 Image 공통 컴포넌트를 맡게 되었으며, 다양한 기술 스택을 적용해 보면서 실력 향상에 초점을 맞추며 구현해 나갔다.

🟢 Icon 컴포넌트

위 아이콘들이 프로젝트 내에서 사용되는 모든 아이콘이다. 이러한 아이콘들을 팀원들이 사용하기 쉽도록 고민을 많이 하였고, 고민한 결과들을 회고해 보려고한다.

어려웠던 점은?

  • 내가 앞으로 구현해야 할 페이지이다. 이 페이지만 봐도 별, 말풍선 아이콘이 사용되고 있고, 심지어 별 아이콘은 같은 페이지 내에서도 크기가 다르며, 모바일, 태블릿, PC 모드에 따라 반응형 동작까지 구현해야 했다.

  • 리팩토링을 하기 전에는 아이콘마다 크기들을 일일이 지정해 주면서 사용자가 좀 더 편하게 type만 전달하여 사용할 수 있게끔 했었지만, 위에서 언급한 이유들로 사용성이 떨어지는 듯한 느낌을 받았다. (className을 추가한 이유)

구현한 코드

고민한 끝에 Icon 컴포넌트는 위와 같이 구현을 했다. Icon 컴포넌트 사용자는 props로 사용하고 싶은 아이콘의 이름, 스타일을 지정하려는 className, 클릭 시 동작하게 하려는 onClick 함수를 넣어 사용할 수 있게 된다.

SVGR

모든 아이콘들은 svg 파일들이다. svg를 좀 더 효율적으로 사용하기 위해 SVGR 라이브러리를 사용했다. SVGR을 사용하면 svg들을 컴포넌트화 시켜줄 수가 있고, prop으로 스타일을 추가해줄 수 있는 특징도 있다.

위와 같이 svg의 fill을 currentColor로 지정해줌으로써 해당 svg를 사용하는 컴포넌트단에서 지정한 색상으로 적용이 된다. 참고로 width, height도 있었지만, 원하는 크기로 자유롭게 지정하기 위해 지워버렸다.

내가 사용한 Icon

테일윈드 스타일을 사용했기 때문에 className에 스타일을 지정해야 했다. 색상을 파란색으로 바꾸고 싶다면 fill-blue로! 그럼 icon이 StarIcon이라 했을 때, 파란색 별 아이콘으로 보이게 된다.

🔵 Loading Icon

두 번째 구현한 아이콘은 로딩 아이콘이다. 마찬가지로 LoadingIcon으로 svg 파일을 import 받아와서 svgr로 사용했다. 앞서 작성한 아이콘과 다른 점이 있다면, 텍스트 부분이다.

이미지속에서는 Loading...으로 표시가 되어 있지만, 다른 목적으로도 사용할 수 있다고 생각해 해당 부분은 children으로 전달받도록 구현했다.

또한, 아이콘의 크기와 텍스트 크기를 고려하여 각 className을 받도록 해주었다.

예상치 못한 이슈

테일윈드를 처음 사용하다보니 className을 사용하는 데 있어 제한되는 부분에서 시간을 많이 보냈다. props로 받아온 className을 Loading 컴포넌트의 className 안에 전달받아 적용이 되도록 구현을 하고자 했지만 적용이 안 되는 것이었다. 테일윈드에서는 className에 정의된 스타일들의 순서가 의미가 없다는 것이었다. 이러한 이유로 무턱대고 className의 맨 뒤에 정의한다고 해도 의미가 없었던 것.

해결 방법

  • twMerge

twMerge라는 라이브러리를 사용하여 정의할 수 있었다. 그럼 충돌되는 부분은 뒤에 명시한 className으로 반영이 되는 것이다. 덮어쓴다는 느낌!

🟣 Logo Icon

gnb에 보여질 로고 아이콘은 따로 className을 받지 않도록 했다. 딱히 스타일 조정이 필요한 것도 아니기 때문에, 내가 지정해 놓는 것이 사용하는 입장에서도 편할 것 같다고 느꼈다. 추후 로고는 다시 디자인 할 생각이기 때문에, 그때 다시 변경할 생각이다.

🟡 Image


이번 프로젝트에서는 next.js를 사용하다보니 Image 태그를 사용함으로써 최적화를 시켜줄 수 있다는 장점이 있었다. 내가 맡은 공통 컴포넌트들은 로직 자체는 단순한데, 사용성을 많이 고려하다보니 시간이 많이 걸렸던 것 같다.

프로젝트 내에서 사용되는 이미지 스타일은 크게 4개로 나눌 수 있다.

이미지 컴포넌트를 사용하는 팀원은 'type' prop으로 4가지 타입 중 하나를 전달하면 그에 맞는 이미지 스타일에 맞게 적용이 되도록 구현을 해보았다. 이 과정에서 다른 스타일을 적용하고 싶은 팀원도 있을 거라 생각을 했다. 그래서 className prop도 추가적으로 받도록 했다.

❗️Image 태그를 div로 감싼 이유는?

위 코드를 보면 Image 컴포넌트를 div태그의 하위요소로 구현이 된 것을 볼 수 있다. 이렇게 하면 어떤 점들을 제공할까? 내가 공부한 바로는 아래와 같다.

  1. div태그를 사용하게 되면 이미지 주변에 추가적인 스타일링이나 레이아웃 제어를 쉽게 할 수 있다는 장점이 있다.
  2. twMerge 함수를 사용함으로써 클래스를 조합하고, 다양한 화면 크기에 대응하는 반응형 디자인을 구현하기 쉽다. 즉, div 태그에 클래스들을 변경함으로써 모바일, 태블릿 PC 너비에 따라 유연하게 UI를 구현할 수 있다.
  3. Next.js의 Image 컴포넌트는 이미지 최적화를 시켜주는 특징이 있다. 다양한 고유 속성들이 있는데, fill, priority 등과 같은 속성들을 사용함으로써 적절한 크기로 로딩, 중요한 이미지는 더 빨리 로딩이 되도록 할 수 있다. 참고로 div 태그에 relative를 사용하게 되면 Image 컴포넌트는 absolute를 자동으로 갖게 되어 UI 면에서 좀 더 복잡한 UI를 쉽게 구성할 수 있다.

🤗 1주차 마무리하며..

공통 컴포넌트를 구현하면서 '사용성'에 가장 많은 신경을 쓰고 구현해 나갔던 것 같다. 좀 아쉬운 부분이 있었다면, 사용성을 고려하다보니 너무 완벽하게 구현하려고 했던 것? 완벽하게 하면 좋겠지만, 이번 프로젝트를 하면서 느낀거는 어느정도 구현됐다고 생각이 되면 다음 차례로 넘어가고, 빠진 부분이 있다면 그때 추가하는 것도 괜찮을 것 같다는 생각이 들었다. 이번에도 사용성에는 무리가 없을 것 같다는 생각이 들었는데, 추가 요청이 들어왔었다. 그럼 다음 주차도 화이팅!

profile
웹 프론트엔드 취업 준비생입니다:)

0개의 댓글