.nav__brand is display:none below 1024px, so "tap the wordmark" was desktop-only. Add a shared onTapCode() helper (src/lib/tap-code.js) and put the 7-tap shortcut on the dex feed's game-title (.feed-head__id), which is visible on every screen size. Keeps the wordmark tap for desktop. 3 tests for onTapCode (count, window reset, unbind). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
76 lines
2.5 KiB
JavaScript
76 lines
2.5 KiB
JavaScript
import { el } from '../lib/dom.js';
|
|
import { openGameSheet } from './GameSheet.js';
|
|
import { settings } from '../store/settings.js';
|
|
import { onTapCode } from '../lib/tap-code.js';
|
|
|
|
const ITEMS = [
|
|
{ label: 'Dex', icon: '▦', href: '#/', match: (h) => h === '#/' || h === '' || h === '#' },
|
|
{
|
|
label: 'Team',
|
|
icon: '⛨',
|
|
href: '#/team',
|
|
match: (h) => h.startsWith('#/team'),
|
|
optional: 'showTeamNav',
|
|
},
|
|
{ label: 'Games', icon: '◉', action: openGameSheet },
|
|
{ label: 'Search', icon: '⌕', href: '#/search', match: (h) => h.startsWith('#/search') },
|
|
{ label: 'Settings', icon: '⚙', href: '#/settings', match: (h) => h.startsWith('#/settings') },
|
|
];
|
|
|
|
/**
|
|
* One nav element, styled by CSS into a bottom bar on phones and a sidebar
|
|
* on wide screens. The Games item summons an overlay; optional items (Team)
|
|
* can be hidden from Settings.
|
|
*/
|
|
export function Nav() {
|
|
const nav = el('nav', { class: 'nav', 'aria-label': 'Primary' });
|
|
let links = [];
|
|
|
|
function build() {
|
|
const st = settings.get();
|
|
const items = ITEMS.filter((it) => !it.optional || st[it.optional]);
|
|
links = items.map((item) => {
|
|
const inner = [
|
|
el('span', { class: 'nav__icon', 'aria-hidden': 'true' }, item.icon),
|
|
el('span', { class: 'nav__label' }, item.label),
|
|
];
|
|
return item.action
|
|
? el(
|
|
'button',
|
|
{ class: 'nav__link', type: 'button', onclick: () => item.action() },
|
|
...inner,
|
|
)
|
|
: el('a', { class: 'nav__link', href: item.href }, ...inner);
|
|
});
|
|
// Easter egg: the wordmark only shows on wide screens; on mobile the
|
|
// same shortcut lives on the dex feed's game title (see DexGrid).
|
|
const brand = el('span', { class: 'nav__brand' }, 'Pocketdex');
|
|
onTapCode(brand, () => {
|
|
if ((location.hash || '') !== '#/whos-that') location.hash = '#/whos-that';
|
|
});
|
|
nav.replaceChildren(brand, ...links);
|
|
nav._items = items;
|
|
sync();
|
|
}
|
|
|
|
function sync() {
|
|
const hash = location.hash || '#/';
|
|
(nav._items || []).forEach((item, i) => {
|
|
if (!item.match) return;
|
|
links[i].classList.toggle('is-active', item.match(hash));
|
|
links[i].setAttribute('aria-current', item.match(hash) ? 'page' : 'false');
|
|
});
|
|
}
|
|
|
|
build();
|
|
let lastShowTeam = settings.get().showTeamNav;
|
|
settings.subscribe((s) => {
|
|
if (s.showTeamNav !== lastShowTeam) {
|
|
lastShowTeam = s.showTeamNav;
|
|
build();
|
|
}
|
|
});
|
|
window.addEventListener('hashchange', sync);
|
|
return nav;
|
|
}
|