feat: allow resetting card and outfit list sorting
Publish GitHub Pages output / publish (push) Successful in 47s

This commit is contained in:
2026-10-08 18:28:55 +09:00
parent a9e140fa85
commit b28a41f14e
4 changed files with 34 additions and 13 deletions
+7 -1
View File
@@ -1,7 +1,13 @@
--- ---
updatedAt: 2026-10-07T12:57:51.000Z updatedAt: 2026-10-08T09:15:32.000Z
--- ---
## 2026년 10월 8일
### 카드·의상 목록 정렬 해제
`IMPROVED` 카드와 의상 효과 목록에 ‘기본 정렬’ 버튼을 추가했습니다. 정렬 가능한 열 제목을 반복해서 누르면 오름차순·내림차순·기본 순서로 전환합니다. 정렬을 해제해도 필터·개화 선택과 펼친 상세는 유지하며, 기본 정렬 상태는 다음 방문에도 유지합니다.
## 2026년 10월 7일 ## 2026년 10월 7일
### 악곡 목록에 재킷 함께 복사 ### 악곡 목록에 재킷 함께 복사
+1
View File
@@ -51,6 +51,7 @@ body:has(.card-catalog) {
.card-catalog .expanded .chevron { border-color: #df4b8a; transform: rotate(225deg) translate(-1px, -1px); } .card-catalog .expanded .chevron { border-color: #df4b8a; transform: rotate(225deg) translate(-1px, -1px); }
.card-catalog .list-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 10px; color: #aab3c3; font-size: 13px; } .card-catalog .list-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 10px; color: #aab3c3; font-size: 13px; }
.card-catalog .list-toolbar p { margin: 0; line-height: 1.6; } .card-catalog .list-toolbar p { margin: 0; line-height: 1.6; }
.card-catalog .list-tools { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; flex-shrink: 0; max-width: 100%; }
.card-catalog .scroll-hint { display: none; margin: 0 0 10px; color: #969fb0; font-size: 12px; } .card-catalog .scroll-hint { display: none; margin: 0 0 10px; color: #969fb0; font-size: 12px; }
.card-catalog .table-panel { container-type: inline-size; overflow-x: auto; overflow-y: hidden; border: 1px solid #2b3240; border-radius: 18px; background: #161b25; } .card-catalog .table-panel { container-type: inline-size; overflow-x: auto; overflow-y: hidden; border: 1px solid #2b3240; border-radius: 18px; background: #161b25; }
+9 -9
View File
@@ -180,9 +180,15 @@
: [...expandedCardIds, cardId]; : [...expandedCardIds, cardId];
} }
function resetSort() {
sortKey = null;
sortDirection = 'asc';
}
function toggleSort(nextSortKey: CardListSortKey) { function toggleSort(nextSortKey: CardListSortKey) {
if (sortKey === nextSortKey) { if (sortKey === nextSortKey) {
sortDirection = sortDirection === 'asc' ? 'desc' : 'asc'; if (sortDirection === 'asc') sortDirection = 'desc';
else resetSort();
return; return;
} }
@@ -192,7 +198,7 @@
function sortButtonLabel(key: CardListSortKey, label: string, currentKey: CardListSortKey | null, direction: SortDirection) { function sortButtonLabel(key: CardListSortKey, label: string, currentKey: CardListSortKey | null, direction: SortDirection) {
if (currentKey !== key) return `${label} 오름차순 정렬`; if (currentKey !== key) return `${label} 오름차순 정렬`;
return `${label} ${direction === 'asc' ? '내림차순' : '오름차순'}으로 변경`; return `${label} ${direction === 'asc' ? '내림차순으로 변경' : '기본 정렬로 변경'}`;
} }
function secondsLabel(seconds: number | null | undefined) { function secondsLabel(seconds: number | null | undefined) {
@@ -400,6 +406,7 @@
<div class="list-toolbar"> <div class="list-toolbar">
<p>수치는 선택한 개화 기준이며, 조건부 스킬은 조건 충족 시 수치입니다. 여러 행을 펼쳐 상세 정보를 함께 비교할 수 있습니다.</p> <p>수치는 선택한 개화 기준이며, 조건부 스킬은 조건 충족 시 수치입니다. 여러 행을 펼쳐 상세 정보를 함께 비교할 수 있습니다.</p>
<div class="list-tools"> <div class="list-tools">
<button class="filter-action" type="button" disabled={sortKey === null} onclick={resetSort} title="정렬을 해제하고 기본 순서로 돌아갑니다.">기본 정렬</button>
<button class="filter-action" type="button" disabled={expandedCardIds.length === 0} onclick={() => expandedCardIds = []}>상세 모두 접기</button> <button class="filter-action" type="button" disabled={expandedCardIds.length === 0} onclick={() => expandedCardIds = []}>상세 모두 접기</button>
<div class="header-level-control"> <div class="header-level-control">
<span>개화</span> <span>개화</span>
@@ -831,13 +838,6 @@
} }
.outfit-link { display: inline-block; margin-top: 4px; color: #ef9abe; font-size: 12px; text-underline-offset: 3px; } .outfit-link { display: inline-block; margin-top: 4px; color: #ef9abe; font-size: 12px; text-underline-offset: 3px; }
.outfit-link:focus-visible { outline: 2px solid #ef9abe; outline-offset: 3px; } .outfit-link:focus-visible { outline: 2px solid #ef9abe; outline-offset: 3px; }
.list-tools {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 10px;
flex-shrink: 0;
}
.skill-card header { .skill-card header {
display: flex; display: flex;
align-items: center; align-items: center;
+17 -3
View File
@@ -87,13 +87,21 @@
expandedIds = expandedIds.includes(id) ? expandedIds.filter(value => value !== id) : [...expandedIds, id]; expandedIds = expandedIds.includes(id) ? expandedIds.filter(value => value !== id) : [...expandedIds, id];
} }
function resetSort() {
sortKey = null;
sortDirection = 'asc';
}
function toggleSort(key: OutfitSortKey) { function toggleSort(key: OutfitSortKey) {
if (sortKey === key) sortDirection = sortDirection === 'asc' ? 'desc' : 'asc'; if (sortKey === key) {
if (sortDirection === 'asc') sortDirection = 'desc';
else resetSort();
}
else { sortKey = key; sortDirection = 'asc'; } else { sortKey = key; sortDirection = 'asc'; }
} }
function sortLabel(key: OutfitSortKey, label: string, currentKey: OutfitSortKey | null, direction: 'asc' | 'desc') { function sortLabel(key: OutfitSortKey, label: string, currentKey: OutfitSortKey | null, direction: 'asc' | 'desc') {
return `${label} ${currentKey !== key ? '오름차순 정렬' : direction === 'asc' ? '내림차순으로 변경' : '오름차순으로 변경'}`; return `${label} ${currentKey !== key ? '오름차순 정렬' : direction === 'asc' ? '내림차순으로 변경' : '기본 정렬로 변경'}`;
} }
function valueLabel(outfit: OutfitEntry, key: OutfitSortKey) { function valueLabel(outfit: OutfitEntry, key: OutfitSortKey) {
@@ -128,7 +136,13 @@
</div> </div>
</section> </section>
<div class="list-toolbar"><p>수치는 조건 충족 시 기준입니다. 행을 눌러 여러 의상의 전체 설명을 함께 확인할 수 있습니다.</p><button type="button" class="filter-action" disabled={!expandedIds.length} onclick={() => expandedIds = []}>상세 모두 접기</button></div> <div class="list-toolbar">
<p>수치는 조건 충족 시 기준입니다. 행을 눌러 여러 의상의 전체 설명을 함께 확인할 수 있습니다.</p>
<div class="list-tools">
<button type="button" class="filter-action" disabled={sortKey === null} onclick={resetSort} title="정렬을 해제하고 기본 순서로 돌아갑니다.">기본 정렬</button>
<button type="button" class="filter-action" disabled={!expandedIds.length} onclick={() => expandedIds = []}>상세 모두 접기</button>
</div>
</div>
<p class="scroll-hint">목록을 좌우로 밀어 모든 항목을 확인할 수 있습니다.</p> <p class="scroll-hint">목록을 좌우로 밀어 모든 항목을 확인할 수 있습니다.</p>
<section class="table-panel" aria-label="의상 효과 목록"> <section class="table-panel" aria-label="의상 효과 목록">
<div class="list-header"><span>멤버</span><span>기수</span><span>의상명</span><span>획득 카드</span><span>발동 조건</span><span>대상</span><span>강화 효과</span><button type="button" class:active={sortKey === 'parameter'} aria-label={sortLabel('parameter', '스탯 증가율', sortKey, sortDirection)} onclick={() => toggleSort('parameter')}><span>스탯<br />증가율</span><span aria-hidden="true">{sortKey === 'parameter' ? sortDirection === 'asc' ? '↑' : '↓' : '↕'}</span></button><button type="button" class:active={sortKey === 'support'} aria-label={sortLabel('support', '스코어 서포트 수치', sortKey, sortDirection)} onclick={() => toggleSort('support')}><span>스코어<br />서포트</span><span aria-hidden="true">{sortKey === 'support' ? sortDirection === 'asc' ? '↑' : '↓' : '↕'}</span></button><span></span></div> <div class="list-header"><span>멤버</span><span>기수</span><span>의상명</span><span>획득 카드</span><span>발동 조건</span><span>대상</span><span>강화 효과</span><button type="button" class:active={sortKey === 'parameter'} aria-label={sortLabel('parameter', '스탯 증가율', sortKey, sortDirection)} onclick={() => toggleSort('parameter')}><span>스탯<br />증가율</span><span aria-hidden="true">{sortKey === 'parameter' ? sortDirection === 'asc' ? '↑' : '↓' : '↕'}</span></button><button type="button" class:active={sortKey === 'support'} aria-label={sortLabel('support', '스코어 서포트 수치', sortKey, sortDirection)} onclick={() => toggleSort('support')}><span>스코어<br />서포트</span><span aria-hidden="true">{sortKey === 'support' ? sortDirection === 'asc' ? '↑' : '↓' : '↕'}</span></button><span></span></div>