dex/src/components/Sprite.js
chris f1abe07128 Add moves, evolution, type matchups, locations; game-accurate data; fix desktop layout
- Detail page: base stats, type matchups (defending), evolution chain,
  learnset with per-move power/type/acc/PP/effect, wild locations
- Game-aware: abilities gated to Gen 3+ (hidden to Gen 5+), type chart
  applies Gen 1 / pre-Gen 6 rules, move stats use PokeAPI past_values,
  pre-Gen 4 physical/special-by-type, evolution tree re-parented to the
  selected generation
- Moves and evolution clickable/expandable; no horizontal scroll
- Fix: .view-host shrink-wrapped as a grid item on desktop (margin:0 auto)
- Era-accurate sprite option; Search tab relabelled as global lookup

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-27 11:35:30 -04:00

55 lines
1.4 KiB
JavaScript

import { el } from '../lib/dom.js';
import { gameSpriteUrl } from '../data/game-sprites.js';
const SPRITES =
'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon';
function pixel(id, shiny) {
return `${SPRITES}${shiny ? '/shiny' : ''}/${id}.png`;
}
/**
* Resolve a sprite URL for a style. `game` uses era-accurate pixel art for
* the selected version group, falling back to HOME art for games that never
* had pixel sprites.
*/
export function spriteUrl(id, style = 'default', shiny = false, versionGroup) {
if (style === 'official') {
return `${SPRITES}/other/official-artwork${shiny ? '/shiny' : ''}/${id}.png`;
}
if (style === 'home') {
return `${SPRITES}/other/home${shiny ? '/shiny' : ''}/${id}.png`;
}
if (style === 'game') {
return (
gameSpriteUrl(id, versionGroup, { shiny }) ||
`${SPRITES}/other/home${shiny ? '/shiny' : ''}/${id}.png`
);
}
return pixel(id, shiny);
}
export function Sprite(
id,
{ style = 'default', shiny = false, versionGroup, alt = '', size = 96 } = {},
) {
const img = el('img', {
class: 'sprite',
loading: 'lazy',
decoding: 'async',
width: size,
height: size,
alt,
src: spriteUrl(id, style, shiny, versionGroup),
});
// Not every form/style has art — degrade to the plain pixel sprite once.
img.addEventListener(
'error',
() => {
img.src = pixel(id, false);
},
{ once: true },
);
return img;
}