페이지네이션 스타일 추가

This commit is contained in:
현성필
2025-12-04 14:34:37 +09:00
parent 81162069da
commit 4f7aa0327e
2 changed files with 204 additions and 20 deletions
@@ -0,0 +1,102 @@
// -----------------------------------------------------------------------------
// Pagination Component
// Based on Figma design: node-id=985-1102
// -----------------------------------------------------------------------------
// Pagination variables
$pagination-gap: 13px;
$pagination-icon-size: 24px;
$pagination-font-size: 18px;
$pagination-text-active: #212529;
$pagination-text-inactive: #5f666c;
$pagination-text-disabled: #adb5bd;
.pagination {
display: flex;
align-items: center;
justify-content: center;
gap: $pagination-gap;
// Page navigation buttons (first, prev, next, last)
.page-first,
.page-prev,
.page-next,
.page-last {
display: flex;
align-items: center;
justify-content: center;
width: $pagination-icon-size;
height: $pagination-icon-size;
color: $pagination-text-active;
text-decoration: none;
cursor: pointer;
transition: $transition-fast;
&:hover:not(.disabled) {
color: $primary-blue;
}
&.disabled {
color: $pagination-text-disabled;
cursor: not-allowed;
pointer-events: none;
}
// SVG icons inherit color from parent
svg {
width: $pagination-icon-size;
height: $pagination-icon-size;
flex-shrink: 0;
}
}
// Page number links
.page-num {
display: flex;
align-items: center;
justify-content: center;
min-width: 10px;
height: 21px;
font-family: $font-family-primary;
font-size: $pagination-font-size;
font-weight: $font-weight-regular;
color: $pagination-text-inactive;
text-decoration: none;
text-align: center;
line-height: 1;
cursor: pointer;
transition: $transition-fast;
&:hover:not(.page-current) {
color: $primary-blue;
}
// Current active page
&.page-current {
font-weight: $font-weight-bold;
color: $pagination-text-active;
cursor: default;
}
}
// Screen reader only text
.blind {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
}
// Pagination wrapper for alignment
.pagination-wrapper {
display: flex;
justify-content: center;
padding: $spacing-lg 0;
margin-top: $spacing-lg;
}
@@ -6,35 +6,117 @@
</head>
<body>
<!-- Static preview for development -->
<div class="pagination">
<a href="#" class="page-prev disabled"><span class="blind">이전페이지</span></a>
<a href="#" class="page-num page-current">1</a>
<a href="#" class="page-first disabled">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 19V5H2.30769V19H0ZM15 19L4.61538 12L15 5V19Z" fill="currentColor"/>
<path d="M24 19L15 12L24 5V19Z" fill="currentColor"/>
</svg>
<span class="blind">처음 페이지</span>
</a>
<a href="#" class="page-prev disabled">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16 5L16 19L5 12L16 5Z" fill="currentColor"/>
</svg>
<span class="blind">이전 페이지</span>
</a>
<a href="#" class="page-num">1</a>
<a href="#" class="page-num">2</a>
<a href="#" class="page-num">3</a>
<a href="#" class="page-num page-current">3</a>
<a href="#" class="page-num">4</a>
<a href="#" class="page-num">5</a>
<a href="#" class="page-next disabled"><span class="blind">다음페이지</span></a>
<a href="#" class="page-next">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8 19V5L19 12L8 19Z" fill="currentColor"/>
</svg>
<span class="blind">다음 페이지</span>
</a>
<a href="#" class="page-last">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M24 5L24 19L21.6923 19L21.6923 5L24 5ZM9 5L19.3846 12L9 19L9 5Z" fill="currentColor"/>
<path d="M1.22392e-06 5L9 12L0 19L1.22392e-06 5Z" fill="currentColor"/>
</svg>
<span class="blind">마지막 페이지</span>
</a>
</div>
<!-- Dynamic Thymeleaf fragment -->
<div th:fragment="pagination" class="pagination"
th:with="index_diff=0,offset_minus2=${ page.getNumber() - 1}, offset_minus1=${ page.getNumber() }, current_page=${ page.getNumber() + 1 }, offset_plus1=${ page.getNumber() + 2 }, offset_plus2=${ page.getNumber() + 3}">
<a class="page-prev" th:classappend="${ current_page == 1}?'disabled'" href="#" th:attr="onclick=|${jsFunction}(1,${page.getSize()});|">
<span class="blind">이전페이지</span>
th:with="index_diff=0, offset_minus2=${page.getNumber() - 1}, offset_minus1=${page.getNumber()}, current_page=${page.getNumber() + 1}, offset_plus1=${page.getNumber() + 2}, offset_plus2=${page.getNumber() + 3}">
<!-- First page button -->
<a class="page-first"
th:classappend="${current_page == 1} ? 'disabled'"
href="#"
th:attr="onclick=|${jsFunction}(1, ${page.getSize()});|">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 19V5H2.30769V19H0ZM15 19L4.61538 12L15 5V19Z" fill="currentColor"/>
<path d="M24 19L15 12L24 5V19Z" fill="currentColor"/>
</svg>
<span class="blind">처음 페이지</span>
</a>
<a class="page-num" th:if="${ offset_minus2 > 0}" href="#" th:attr="onclick=|${jsFunction}(${offset_minus2 - index_diff },${page.getSize()});|">
<span aria-hidden="true" th:text="${offset_minus2}"></span>
<!-- Previous page button -->
<a class="page-prev"
th:classappend="${current_page == 1} ? 'disabled'"
href="#"
th:attr="onclick=|${jsFunction}(${current_page - 1 > 0 ? current_page - 1 : 1}, ${page.getSize()});|">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16 5L16 19L5 12L16 5Z" fill="currentColor"/>
</svg>
<span class="blind">이전 페이지</span>
</a>
<a class="page-num" href="#" th:if="${ offset_minus1 > 0}" th:attr="onclick=|${jsFunction}(${offset_minus1 - index_diff },${page.getSize()});|">
<span aria-hidden="true" th:text="${offset_minus1 }"></span>
<!-- Page numbers -->
<a class="page-num"
th:if="${offset_minus2 > 0}"
href="#"
th:attr="onclick=|${jsFunction}(${offset_minus2 - index_diff}, ${page.getSize()});|"
th:text="${offset_minus2}"></a>
<a class="page-num"
th:if="${offset_minus1 > 0}"
href="#"
th:attr="onclick=|${jsFunction}(${offset_minus1 - index_diff}, ${page.getSize()});|"
th:text="${offset_minus1}"></a>
<a class="page-num page-current"
th:text="${current_page}"></a>
<a class="page-num"
th:if="${offset_plus1 <= page.getTotalPages()}"
href="#"
th:attr="onclick=|${jsFunction}(${offset_plus1 - index_diff}, ${page.getSize()});|"
th:text="${offset_plus1}"></a>
<a class="page-num"
th:if="${offset_plus2 <= page.getTotalPages()}"
href="#"
th:attr="onclick=|${jsFunction}(${offset_plus2 - index_diff}, ${page.getSize()});|"
th:text="${offset_plus2}"></a>
<!-- Next page button -->
<a class="page-next"
th:classappend="${(page.getTotalPages()) - current_page <= 0} ? 'disabled'"
href="#"
th:attr="onclick=|${jsFunction}(${current_page + 1 <= page.getTotalPages() ? current_page + 1 : page.getTotalPages()}, ${page.getSize()});|">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8 19V5L19 12L8 19Z" fill="currentColor"/>
</svg>
<span class="blind">다음 페이지</span>
</a>
<a class="page-num page-current" th:text="${current_page}"></a>
<a class="page-num" th:if="${offset_plus1 <= page.getTotalPages()}" href="#" th:attr="onclick=|${jsFunction}(${offset_plus1 - index_diff },${page.getSize()});|">
<span aria-hidden="true" th:text="${offset_plus1}"></span>
</a>
<a class="page-num" th:if="${offset_plus2 <= page.getTotalPages()}" href="#" th:attr="onclick=|${jsFunction}(${offset_plus2 - index_diff },${page.getSize()});|">
<span aria-hidden="true" th:text="${offset_plus2}"></span>
</a>
<a class="page-next" th:classappend="${ (page.getTotalPages()) - current_page <= 0 } ? 'disabled'" href="#" th:attr="onclick=|${jsFunction}(${page.getTotalPages() - index_diff },${page.getSize()});|">
<span class="blind">다음페이지</span>
<!-- Last page button -->
<a class="page-last"
th:classappend="${(page.getTotalPages()) - current_page <= 0} ? 'disabled'"
href="#"
th:attr="onclick=|${jsFunction}(${page.getTotalPages() - index_diff}, ${page.getSize()});|">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M24 5L24 19L21.6923 19L21.6923 5L24 5ZM9 5L19.3846 12L9 19L9 5Z" fill="currentColor"/>
<path d="M1.22392e-06 5L9 12L0 19L1.22392e-06 5Z" fill="currentColor"/>
</svg>
<span class="blind">마지막 페이지</span>
</a>
</div>