From c2e71ccf75a39da5b889341d95d76e0263378b93 Mon Sep 17 00:00:00 2001 From: Oscar Bakkeng Date: Thu, 17 Sep 2026 15:33:05 +0200 Subject: [PATCH] =?UTF-8?q?Lagt=20til=20funksjon:=20Drop=20down=20meny=20n?= =?UTF-8?q?=C3=A5r=20du=20klikker=20p=C3=A5=20search=20baren,=20som=20load?= =?UTF-8?q?er=20de=20X=20siste=20s=C3=B8kene=20dine=20ved=20bruk=20av=20se?= =?UTF-8?q?ssion=20storage.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.css | 46 ++++++++++++++++++++++++++++++- src/App.tsx | 79 ++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 114 insertions(+), 11 deletions(-) diff --git a/src/App.css b/src/App.css index d27aa90..5b47a50 100644 --- a/src/App.css +++ b/src/App.css @@ -35,9 +35,15 @@ height: 52px; } -.search-form input { +.search-input-wrapper { + position: relative; flex: 1; min-width: 0; +} + +.search-form input { + width: 100%; + box-sizing: border-box; padding: 13px 18px; border: 2px solid var(--border); border-radius: 999px; @@ -55,6 +61,44 @@ box-shadow: 0 0 0 4px var(--accent-bg); } +.recent-searches { + position: absolute; + top: calc(100% + 8px); + left: 0; + right: 0; + z-index: 10; + margin: 0; + padding: 6px; + list-style: none; + background: var(--bg); + border: 2px solid var(--border); + border-radius: 16px; + box-shadow: 0 12px 24px rgb(0 0 0 / 12%); +} + +.recent-searches li + li { + margin-top: 2px; +} + +.recent-searches button { + display: block; + width: 100%; + padding: 10px 14px; + border: 0; + border-radius: 10px; + background: transparent; + color: var(--text-h); + font: inherit; + text-align: left; + cursor: pointer; +} + +.recent-searches button:hover, +.recent-searches button:focus-visible { + background: var(--accent-bg); + outline: none; +} + .search-form button { padding: 0 26px; border: 0; diff --git a/src/App.tsx b/src/App.tsx index 7bd108f..00cac48 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -7,6 +7,18 @@ import FavoritesSidebar from './FavoritesSidebar'; import './App.css'; const SEARCH_STORAGE_KEY = 'pokemon-search'; +const RECENT_SEARCHES_STORAGE_KEY = 'pokemon-recent-searches'; +const MAX_RECENT_SEARCHES = 5; + +function loadRecentSearches(): string[] { + try { + const raw = sessionStorage.getItem(RECENT_SEARCHES_STORAGE_KEY); + const parsed = raw ? JSON.parse(raw) : []; + return Array.isArray(parsed) ? parsed : []; + } catch { + return []; + } +} function capitalize(text: string): string { return text.charAt(0).toUpperCase() + text.slice(1); @@ -33,6 +45,8 @@ function App() { ); const [error, setError] = useState(''); + const [recentSearches, setRecentSearches] = useState(loadRecentSearches); + const [showSuggestions, setShowSuggestions] = useState(false); const { favorites, isFavorite, toggleFavorite } = useFavorites(); @@ -44,9 +58,23 @@ function App() { .slice(0, 24) : []; - function handleSearch(event: FormEvent) { - event.preventDefault(); - const trimmedQuery = query.trim(); + function addToRecentSearches(trimmedQuery: string) { + const withoutDuplicate = recentSearches.filter( + (entry) => entry.toLowerCase() !== trimmedQuery.toLowerCase(), + ); + const updated = [trimmedQuery, ...withoutDuplicate].slice( + 0, + MAX_RECENT_SEARCHES, + ); + setRecentSearches(updated); + sessionStorage.setItem( + RECENT_SEARCHES_STORAGE_KEY, + JSON.stringify(updated), + ); + } + + function runSearch(rawQuery: string) { + const trimmedQuery = rawQuery.trim(); if (!trimmedQuery) { setSubmittedQuery(''); @@ -57,6 +85,18 @@ function App() { sessionStorage.setItem(SEARCH_STORAGE_KEY, trimmedQuery); setSubmittedQuery(trimmedQuery); setError(''); + addToRecentSearches(trimmedQuery); + } + + function handleSearch(event: FormEvent) { + event.preventDefault(); + runSearch(query); + } + + function handleSelectRecentSearch(recentQuery: string) { + setQuery(recentQuery); + setShowSuggestions(false); + runSearch(recentQuery); } return ( @@ -70,13 +110,32 @@ function App() { «pikachu».

- setQuery(event.target.value)} - placeholder="For eksempel: bulba" - aria-label="Søk etter Pokémon" - /> +
+ setQuery(event.target.value)} + onFocus={() => setShowSuggestions(true)} + onBlur={() => setShowSuggestions(false)} + placeholder="For eksempel: bulba" + aria-label="Søk etter Pokémon" + /> + {showSuggestions && recentSearches.length > 0 && ( +
    + {recentSearches.map((recentQuery) => ( +
  • + +
  • + ))} +
+ )} +