feat: release version 1.0.7
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { songOptions, type SongChartSummary, type SongSort } from '$lib/data/song-catalog.ts';
|
||||
|
||||
export let charts: readonly SongChartSummary[];
|
||||
export let difficulty: string;
|
||||
export let value: string;
|
||||
|
||||
const dispatch = createEventDispatcher<{ change: void }>();
|
||||
let query = '';
|
||||
let sort: SongSort = 'title';
|
||||
|
||||
$: options = songOptions(charts, difficulty, query, sort);
|
||||
|
||||
function selectSong(event: Event) {
|
||||
const nextValue = (event.currentTarget as HTMLSelectElement).value;
|
||||
if (!nextValue) return;
|
||||
value = nextValue;
|
||||
dispatch('change');
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="song-picker">
|
||||
<label class="song-search">
|
||||
<span>악곡 검색</span>
|
||||
<input bind:value={query} type="search" placeholder="영문 곡명 검색" autocomplete="off">
|
||||
</label>
|
||||
<label class="song-sort">
|
||||
<span>정렬</span>
|
||||
<select bind:value={sort}>
|
||||
<option value="title">알파벳순</option>
|
||||
<option value="difficulty-asc">난이도 낮은순</option>
|
||||
<option value="difficulty-desc">난이도 높은순</option>
|
||||
</select>
|
||||
</label>
|
||||
<label class="song-select">
|
||||
<span>악곡 <small>{options.length}곡</small></span>
|
||||
<select value={value} on:change={selectSong} disabled={options.length === 0}>
|
||||
{#if options.length === 0}
|
||||
<option>검색 결과가 없습니다</option>
|
||||
{:else}
|
||||
{#if !options.some((song) => song.id === value)}
|
||||
<option value="" disabled>검색 결과에서 악곡을 선택하세요</option>
|
||||
{/if}
|
||||
{#each options as song}
|
||||
<option value={song.id}>{song.title}{song.difficultyLevel === null ? '' : ` · Lv. ${song.difficultyLevel}`}</option>
|
||||
{/each}
|
||||
{/if}
|
||||
</select>
|
||||
</label>
|
||||
{#if query.trim()}
|
||||
<p class:no-results={options.length === 0} class="search-status" aria-live="polite">
|
||||
{options.length > 0
|
||||
? `${options.length}곡을 찾았습니다. 목록에서 선택하세요.`
|
||||
: '검색 결과가 없습니다.'}
|
||||
</p>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.song-picker { display: grid; grid-template-columns: minmax(180px, .9fr) minmax(140px, .55fr) minmax(260px, 1.4fr); gap: 9px; }
|
||||
label { display: grid; gap: 7px; min-width: 0; color: #8f98a8; font-size: 14px; font-weight: 750; }
|
||||
label > span { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
|
||||
small { color: #737d8d; font-size: 11px; }
|
||||
input, select { width: 100%; min-width: 0; height: 42px; padding: 0 12px; border: 1px solid #343c49; border-radius: 9px; color: #e8ebf1; background: #11151b; font: inherit; }
|
||||
input::placeholder { color: #68717f; opacity: 1; }
|
||||
input:focus, select:focus { border-color: #d86f9c; outline: 3px solid rgb(216 111 156 / 14%); }
|
||||
select:disabled { color: #747d8b; }
|
||||
.search-status { grid-column: 1 / -1; margin: -1px 2px 0; color: #8fa99c; font-size: 12px; font-weight: 750; line-height: 1.45; }
|
||||
.search-status.no-results { color: #d09494; }
|
||||
@media (max-width: 900px) {
|
||||
.song-picker { grid-template-columns: 1fr minmax(140px, .55fr); }
|
||||
.song-select { grid-column: 1 / -1; }
|
||||
}
|
||||
@media (max-width: 520px) {
|
||||
.song-picker { grid-template-columns: 1fr; }
|
||||
.song-select { grid-column: auto; }
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user