-
Notifications
You must be signed in to change notification settings - Fork 4
✨ Feat: 공통 컴포넌트 Pagination 설계 #33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| import { Icon } from '@/components/ui'; | ||
| import { useState } from 'react'; | ||
|
|
||
| const PAGE_GROUP_SIZE = 7; | ||
| const ITEMS_PER_PAGE = 5; | ||
|
|
||
| interface PaginationProps { | ||
| totalItems: number; | ||
| } | ||
| // totalItems 는 API 통신 시 Response 로 받는 """count""" 부모로부터 넘겨주기! | ||
|
|
||
| const Pagination = ({ totalItems }: PaginationProps) => { | ||
| const [currentPage, setCurrentPage] = useState(totalItems > 0 ? 1 : 0); | ||
| // [currentPage, setCurrentPage] 는 부모 페이지에서 받아올 데이터 내용 | ||
| // - 그래야 페이지 바뀔 때 부모 페이지에 state 영향 줘서 리렌더링해서 화면 다시 보여줌 | ||
| // - 이후 페이지 작업 시 위의 state 선언은 부모페이지에서 하고 값들 props 로 받기 | ||
| const [pageGroup, setPageGroup] = useState(0); | ||
|
|
||
| const totlaPages = Math.ceil(totalItems / ITEMS_PER_PAGE); | ||
| if (totlaPages === 0) return null; | ||
|
||
| const startPage = pageGroup * PAGE_GROUP_SIZE + 1; | ||
| const endPage = Math.min(startPage + PAGE_GROUP_SIZE - 1, totlaPages); | ||
| const pageNumbers = Array.from({ length: endPage - startPage + 1 }, (_, i) => startPage + i); | ||
| const isPrevDisabled = pageGroup === 0; | ||
| const isNextDisabled = (pageGroup + 1) * PAGE_GROUP_SIZE >= totlaPages; | ||
|
|
||
| return ( | ||
| <> | ||
| <div className='flex h-14 items-center justify-center bg-white tablet:h-16'> | ||
| <div className='flex h-8 items-center justify-center gap-[2px] px-3 py-2 tablet:h-10'> | ||
| <Icon | ||
| className={`h-5 w-5 ${isPrevDisabled ? 'bg-gray-400' : 'cursor-pointer'}`} | ||
| onClick={() => { | ||
| if (!isPrevDisabled) { | ||
| setPageGroup(prev => Math.max(prev - 1, 0)); | ||
| } | ||
| }} | ||
| iconName='chevronLeft' | ||
| ariaLabel='이전' | ||
| /> | ||
|
||
| {pageNumbers.map(page => ( | ||
| <button | ||
| key={page} | ||
| onClick={() => setCurrentPage(page)} | ||
| className={ | ||
| page === currentPage | ||
| ? 'h-8 w-8 rounded bg-red-300 text-caption text-white tablet:text-body-s' | ||
| : 'h-8 w-8 text-caption tablet:text-body-s' | ||
| } | ||
| > | ||
| {page} | ||
| </button> | ||
| ))} | ||
| <Icon | ||
| className={`h-5 w-5 ${isNextDisabled ? 'bg-gray-400' : 'cursor-pointer'}`} | ||
| onClick={() => { | ||
| if (!isNextDisabled) { | ||
| setPageGroup(prev => ((prev + 1) * PAGE_GROUP_SIZE < totlaPages ? prev + 1 : prev)); | ||
| } | ||
| }} | ||
| iconName='chevronRight' | ||
| ariaLabel='이후' | ||
| /> | ||
| </div> | ||
| </div> | ||
| </> | ||
| ); | ||
| }; | ||
|
|
||
| export default Pagination; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
그렇다면 prop자체를 {totalItems, currentPage, onPageChange} 로 작성하는건 어떠실까요!? 부모페이지에서 받아올 데이터 내용이면 Prop 에 작성이 되어야 할텐데 props 엔 전체 아이템만 받고 있는것 같아서요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
네! 안그래도 위의 내용은 페이지 작업때 다루어질 것 같아 최대한 설명을 드리고 싶어서 적어놨습니다 :)
부모 컴포넌트에서 onPageChange 로 currentPage 의 state 변경하는 함수 만들어서 props 로 내려주는 형식으로 다같이 가져간다 생각을 하고 말씀하신대로 수정하겠습니다!
추가적으로, 피그마 시안을 다시 봤더니 인화님 페이지는 데이터 5개 / 소현님 페이지는 데이터 6개로 다르더라고요! 그래서 상수 빼고 itemsPerPage 로 페이지 하나하나마다 받아오는 데이터개수도 props 로 내릴 수 있게 변경하겠습니다!