- 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>
36 lines
1.1 KiB
JavaScript
36 lines
1.1 KiB
JavaScript
import { el } from '../lib/dom.js';
|
||
import { TypeChip } from './TypeChip.js';
|
||
import { defensiveMatchups } from '../data/type-chart.js';
|
||
|
||
const GROUPS = [
|
||
{ key: '4', label: '4× damage', cls: 'x4' },
|
||
{ key: '2', label: '2× damage', cls: 'x2' },
|
||
{ key: '0.5', label: '½× damage', cls: 'half' },
|
||
{ key: '0.25', label: '¼× damage', cls: 'quarter' },
|
||
{ key: '0', label: 'No effect', cls: 'zero' },
|
||
];
|
||
|
||
/** Defensive type effectiveness for the given Pokémon types. */
|
||
export function TypeMatchups(types, gen = 9) {
|
||
const buckets = defensiveMatchups(types, gen);
|
||
const wrap = el('div', { class: 'matchups' });
|
||
|
||
for (const g of GROUPS) {
|
||
const list = buckets[g.key];
|
||
if (!list.length) continue;
|
||
wrap.append(
|
||
el(
|
||
'div',
|
||
{ class: `matchups__row matchups__row--${g.cls}` },
|
||
el('span', { class: 'matchups__label' }, g.label),
|
||
el('span', { class: 'matchups__types' }, ...list.map(TypeChip)),
|
||
),
|
||
);
|
||
}
|
||
|
||
if (!wrap.children.length) {
|
||
return el('p', { class: 'detail__muted' }, 'Takes normal damage from every type.');
|
||
}
|
||
return wrap;
|
||
}
|