SPB Git forge
15commits 1branches 0releases
29.7 MBsize
maindefault branch
10 days agolast push
TypeScript 36.3% Python 31.8% Go 18% JavaScript 9.8% Shell 1.9% SQL 1.4% CSS 0.5%
1.4 KB · 39 lines tsx
Raw Blame History
1'use client';23import { useRef } from 'react';4import { MODES, type MapMode } from './modes';56/** Keyboard-navigable radiogroup (←/→ move, space/enter select). */7export function ModeSelector({ mode, onChange }: { mode: MapMode; onChange: (m: MapMode) => void }) {8  const ref = useRef<HTMLDivElement>(null);9  const onKey = (e: React.KeyboardEvent, i: number) => {10    let next = i;11    if (e.key === 'ArrowRight') next = (i + 1) % MODES.length;12    else if (e.key === 'ArrowLeft') next = (i - 1 + MODES.length) % MODES.length;13    else if (e.key === 'Home') next = 0;14    else if (e.key === 'End') next = MODES.length - 1;15    else return;16    e.preventDefault();17    onChange(MODES[next]!.id);18    (ref.current?.children[next] as HTMLElement | undefined)?.focus();19  };20  return (21    <div ref={ref} role="radiogroup" aria-label="Map mode" className="scroll-x -mx-3 flex gap-1 px-3 pb-1 sm:mx-0 sm:flex-wrap sm:px-0">22      {MODES.map((m, i) => (23        <button24          key={m.id}25          type="button"26          role="radio"27          aria-checked={mode === m.id}28          tabIndex={mode === m.id ? 0 : -1}29          onClick={() => onChange(m.id)}30          onKeyDown={(e) => onKey(e, i)}31          className={`whitespace-nowrap rounded-[3px] border px-2 py-1 text-[11px] tracking-[0.04em] ${mode === m.id ? 'border-line-2 bg-panel-2 text-ink' : 'border-line text-ink-2 hover:text-ink'}`}32        >33          {m.label}34        </button>35      ))}36    </div>37  );38}39