Skip to content

Commit bae58c2

Browse files
authored
Enhance search bar styling to fit theme (#48)
1 parent 9b6c58f commit bae58c2

2 files changed

Lines changed: 133 additions & 35 deletions

File tree

frontend/leaderboard.html

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,19 @@ <h1 class="page-title">Leaderboard</h1>
4242

4343

4444
<div class="search-container">
45-
<input
46-
type="text"
47-
id="leaderboard-search"
48-
class="search-input"
49-
placeholder="./search_by_name_or_leetcode_id"
50-
autocomplete="off"
51-
>
45+
<div class="search-bar">
46+
<span class="search-prefix">$ grep -i</span>
47+
<input
48+
type="text"
49+
id="leaderboard-search"
50+
class="search-input"
51+
placeholder="pattern"
52+
autocomplete="off"
53+
spellcheck="false"
54+
>
55+
<span class="search-result-count" id="search-result-count"></span>
56+
<kbd class="search-shortcut" id="search-shortcut">Ctrl+K</kbd>
57+
</div>
5258
</div>
5359

5460
<div class="leaderboard">
@@ -107,12 +113,37 @@ <h1 class="page-title">Leaderboard</h1>
107113
});
108114

109115
const searchInput = document.getElementById('leaderboard-search');
116+
const shortcutBadge = document.getElementById('search-shortcut');
110117

111118
searchInput.addEventListener('input', (e) => {
112119
currentSearchTerm = e.target.value.toLowerCase().trim();
113120
applyFiltersAndRender();
114121
});
115122

123+
searchInput.addEventListener('focus', () => {
124+
shortcutBadge.style.opacity = '0';
125+
});
126+
127+
searchInput.addEventListener('blur', () => {
128+
if (!searchInput.value) {
129+
shortcutBadge.style.opacity = '1';
130+
}
131+
});
132+
133+
// Ctrl+K / Cmd+K keyboard shortcut
134+
document.addEventListener('keydown', (e) => {
135+
if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
136+
e.preventDefault();
137+
searchInput.focus();
138+
}
139+
if (e.key === 'Escape' && document.activeElement === searchInput) {
140+
searchInput.value = '';
141+
currentSearchTerm = '';
142+
searchInput.blur();
143+
applyFiltersAndRender();
144+
}
145+
});
146+
116147
fetchLeaderboardData();
117148
});
118149

@@ -214,12 +245,25 @@ <h1 class="page-title">Leaderboard</h1>
214245
}));
215246

216247
const filteredData = rankedData.filter(user => {
248+
if (!currentSearchTerm) return true;
217249
return (
218250
user.name.toLowerCase().includes(currentSearchTerm) ||
219251
user.id.toLowerCase().includes(currentSearchTerm)
220252
);
221253
});
222254

255+
// Update result count
256+
const countEl = document.getElementById('search-result-count');
257+
if (currentSearchTerm) {
258+
const total = originalData.length;
259+
const matched = filteredData.length;
260+
countEl.textContent = `${matched}/${total}`;
261+
countEl.style.opacity = '1';
262+
} else {
263+
countEl.textContent = '';
264+
countEl.style.opacity = '0';
265+
}
266+
223267
renderLeaderboard(filteredData);
224268
}
225269

@@ -309,7 +353,7 @@ <h1 class="page-title">Leaderboard</h1>
309353
mobileCards.appendChild(card);
310354
});
311355

312-
if (data.length > currentDisplayLimit) {
356+
if (!isSearching && data.length > currentDisplayLimit) {
313357
document.getElementById('load-more-btn').style.display = 'inline-block';
314358
document.getElementById('scroll-top-btn').style.display = 'none';
315359

@@ -323,7 +367,7 @@ <h1 class="page-title">Leaderboard</h1>
323367
}
324368
} else {
325369
document.getElementById('load-more-btn').style.display = 'none';
326-
document.getElementById('scroll-top-btn').style.display = 'inline-block';
370+
document.getElementById('scroll-top-btn').style.display = isSearching ? 'none' : 'inline-block';
327371
}
328372
}
329373

frontend/styles/main.css

Lines changed: 80 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1920,42 +1920,96 @@ body::-webkit-scrollbar-thumb {
19201920

19211921

19221922

1923+
/* ── Search Bar ── */
19231924
.search-container {
1924-
display: flex;
1925-
justify-content: center;
1926-
margin-bottom: 1.5rem;
1925+
display: flex;
1926+
justify-content: center;
1927+
margin-bottom: 2rem;
1928+
padding: 0 1rem;
1929+
}
1930+
1931+
.search-bar {
1932+
display: flex;
1933+
align-items: center;
1934+
gap: 8px;
1935+
background: var(--bg-surface);
1936+
border: 1px solid var(--border);
1937+
border-radius: 4px;
1938+
padding: 0.55rem 1rem;
1939+
width: 100%;
1940+
max-width: 420px;
1941+
transition: border-color 0.2s ease, box-shadow 0.2s ease;
1942+
}
1943+
1944+
.search-bar:focus-within {
1945+
border-color: var(--green-dim);
1946+
box-shadow: 0 0 12px rgba(0, 255, 65, 0.06), 0 0 0 1px rgba(0, 255, 65, 0.08);
1947+
}
1948+
1949+
.search-prefix {
1950+
color: var(--text-muted);
1951+
font-family: 'Fira Code', monospace;
1952+
font-size: 0.82rem;
1953+
white-space: nowrap;
1954+
user-select: none;
1955+
flex-shrink: 0;
1956+
transition: color 0.2s ease;
1957+
}
1958+
1959+
.search-bar:focus-within .search-prefix {
1960+
color: var(--green-dim);
19271961
}
19281962

19291963
.search-input {
1930-
width: 100%;
1931-
max-width: 420px;
1932-
padding: 0.9rem 1rem;
1933-
background: rgba(0, 0, 0, 0.7);
1934-
border: 1px solid var(--cyan);
1935-
color: var(--text);
1936-
font-family: 'Fira Code', monospace;
1937-
font-size: 0.9rem;
1938-
outline: none;
1939-
transition: all 0.2s ease;
1940-
box-shadow: 0 0 10px rgba(0, 229, 255, 0.08);
1964+
flex: 1;
1965+
background: transparent;
1966+
border: none;
1967+
outline: none;
1968+
color: var(--green);
1969+
font-family: 'Fira Code', monospace;
1970+
font-size: 0.88rem;
1971+
caret-color: var(--green);
1972+
min-width: 0;
1973+
padding: 0;
1974+
box-shadow: none !important;
19411975
}
19421976

19431977
.search-input::placeholder {
1944-
color: var(--text-muted);
1945-
font-family: 'Fira Code', monospace;
1978+
color: var(--text-muted);
1979+
font-style: italic;
1980+
opacity: 0.6;
1981+
}
1982+
1983+
.search-result-count {
1984+
color: var(--text-dim);
1985+
font-family: 'Fira Code', monospace;
1986+
font-size: 0.72rem;
1987+
white-space: nowrap;
1988+
opacity: 0;
1989+
transition: opacity 0.15s ease;
1990+
flex-shrink: 0;
19461991
}
19471992

1948-
.search-input:focus {
1949-
border-color: var(--green);
1950-
box-shadow: 0 0 12px rgba(0, 255, 100, 0.2);
1993+
.search-shortcut {
1994+
display: inline-flex;
1995+
align-items: center;
1996+
padding: 2px 6px;
1997+
font-family: 'Fira Code', monospace;
1998+
font-size: 0.65rem;
1999+
color: var(--text-muted);
2000+
background: var(--bg-raised);
2001+
border: 1px solid var(--border);
2002+
border-radius: 3px;
2003+
white-space: nowrap;
2004+
flex-shrink: 0;
2005+
transition: opacity 0.15s ease;
2006+
user-select: none;
19512007
}
19522008

19532009
.no-results {
1954-
text-align: center;
1955-
padding: 2rem;
1956-
color: var(--text-muted);
1957-
font-family: 'Fira Code', monospace;
1958-
border: 1px dashed rgba(0, 229, 255, 0.2);
1959-
background: rgba(0, 0, 0, 0.3);
1960-
margin-top: 1rem;
2010+
text-align: center;
2011+
padding: 2rem 1rem;
2012+
color: var(--text-muted);
2013+
font-family: 'Fira Code', monospace;
2014+
font-size: 0.85rem;
19612015
}

0 commit comments

Comments
 (0)