diff --git a/src/App.css b/src/App.css index 168968a..2cb0fb8 100644 --- a/src/App.css +++ b/src/App.css @@ -381,9 +381,11 @@ .pokemon-card { position: relative; width: min(100%, 620px); + height: 420px; margin: 24px auto; padding: 20px; box-sizing: border-box; + overflow-y: auto; border: 1px solid var(--accent-border); border-radius: 18px; @@ -392,6 +394,78 @@ box-shadow: var(--shadow); } +.skeleton { + background: linear-gradient( + 100deg, + var(--border) 25%, + var(--bg) 50%, + var(--border) 75% + ); + background-size: 200% 100%; + animation: skeleton-loading 1.5s ease-in-out infinite; +} + +.skeleton-image { + width: 100px; + height: 100px; + flex: 0 0 auto; + border-radius: 50%; +} + +.skeleton-header-text { + display: grid; + gap: 10px; + width: min(220px, 100%); +} + +.skeleton-title { + width: 75%; + height: 25px; + border-radius: 6px; +} + +.skeleton-subtitle { + width: 48%; + height: 17px; + border-radius: 5px; +} + +.skeleton-label { + width: 35%; + height: 17px; + border-radius: 5px; +} + +.skeleton-value { + width: 100%; + height: 38px; + border-radius: 10px; +} + +.skeleton-section-title { + width: 85px; + height: 18px; + border-radius: 5px; +} + +.skeleton-stat { + width: 100%; + height: 20px; + border-radius: 8px; +} + +@keyframes skeleton-loading { + to { + background-position: -200% 0; + } +} + +@media (prefers-reduced-motion: reduce) { + .skeleton { + animation: none; + } +} + .pokemon-card-close { position: absolute; top: 10px; @@ -523,6 +597,11 @@ padding: 16px; } + .skeleton-image { + width: 80px; + height: 80px; + } + .pokemon-card-header img { width: 80px; height: 80px; diff --git a/src/PokemonDetails.tsx b/src/PokemonDetails.tsx index 43d75ec..3142637 100644 --- a/src/PokemonDetails.tsx +++ b/src/PokemonDetails.tsx @@ -38,24 +38,22 @@ function PokemonDetails({ ); } - if (isPending) { - return
Loading Pokémon details...
; - } - - if (isError || selectedPokemon === null) { - returnCould not load Pokémon details.
; - } - - const statRows = Array.from( - { length: Math.ceil(selectedPokemon.stats.length / 3) }, - (_, rowIndex) => selectedPokemon.stats.slice(rowIndex * 3, rowIndex * 3 + 3) - ); - - const favorite = isFavorite(selectedPokemon.id); - const name = capitalize(selectedPokemon.name); + const statRows = selectedPokemon + ? Array.from( + { length: Math.ceil(selectedPokemon.stats.length / 3) }, + (_, rowIndex) => + selectedPokemon.stats.slice(rowIndex * 3, rowIndex * 3 + 3) + ) + : []; + const favorite = selectedPokemon ? isFavorite(selectedPokemon.id) : false; + const name = selectedPokemon ? capitalize(selectedPokemon.name) : ''; return ( -