Keyboard Navigation

Operation without a pointer.

Arrow keys: · current item ring shows focus

html

<div class="kb-demo" data-orientation="horizontal" data-current="item-1" style="--accent:#BFD9F2;">
  <div class="kb-demo__list">
    <a href="#" class="kb-demo__item kb-demo__item--item-1"><span class="kb-demo__num">1</span>Overview</a>
    <a href="#" class="kb-demo__item kb-demo__item--item-2"><span class="kb-demo__num">2</span>Reports</a>
    <a href="#" class="kb-demo__item kb-demo__item--item-3"><span class="kb-demo__num">3</span>Settings</a>
  </div>
  <p class="kb-demo__hint">Arrow keys: <span class="kb-demo__key"></span> &middot; current item ring shows focus</p>
</div>
<style>
.kb-demo { width: 320px; font: 14px system-ui, sans-serif; color: #241430; }
.kb-demo__list { display: flex; gap: 8px; }
.kb-demo[data-orientation="vertical"] .kb-demo__list { flex-direction: column; }
.kb-demo__item { display: flex; align-items: center; gap: 6px; padding: 9px 14px; border-radius: 8px; border: 1.5px solid #24143022; text-decoration: none; color: #241430; }
.kb-demo__num { width: 16px; height: 16px; border-radius: 50%; background: #24143014; font-size: 10px; display: grid; place-items: center; font-weight: 700; }
.kb-demo[data-current="item-1"] .kb-demo__item--item-1, .kb-demo[data-current="item-2"] .kb-demo__item--item-2, .kb-demo[data-current="item-3"] .kb-demo__item--item-3 { outline: 2px solid var(--accent); outline-offset: 2px; background: #FAF7F2; }
.kb-demo__hint { margin-top: 12px; font-size: 12px; color: #241430aa; }
.kb-demo__key::before { content: "\2192"; }
.kb-demo[data-orientation="vertical"] .kb-demo__key::before { content: "\2193"; }
</style>

tailwind

<div class="kb-tw kb-tw--horizontal kb-tw-cur--item-1" style="width:320px;font-family:system-ui,sans-serif;color:#241430">
  <div class="kb-tw__list flex gap-2">
    <a href="#" class="kb-tw__item kb-tw__item--item-1 flex items-center gap-1.5 px-3.5 py-2 rounded-lg border no-underline text-[#241430]" style="border-color:#24143022"><span class="w-4 h-4 rounded-full bg-[#24143014] text-[10px] grid place-items-center font-bold">1</span>Overview</a>
    <a href="#" class="kb-tw__item kb-tw__item--item-2 flex items-center gap-1.5 px-3.5 py-2 rounded-lg border no-underline text-[#241430]" style="border-color:#24143022"><span class="w-4 h-4 rounded-full bg-[#24143014] text-[10px] grid place-items-center font-bold">2</span>Reports</a>
    <a href="#" class="kb-tw__item kb-tw__item--item-3 flex items-center gap-1.5 px-3.5 py-2 rounded-lg border no-underline text-[#241430]" style="border-color:#24143022"><span class="w-4 h-4 rounded-full bg-[#24143014] text-[10px] grid place-items-center font-bold">3</span>Settings</a>
  </div>
  <p class="mt-3 text-xs text-[#241430aa]">Arrow keys move focus &middot; current item ring shows focus</p>
</div>
<style>
.kb-tw--vertical .kb-tw__list { flex-direction: column; }
.kb-tw-cur--item-1 .kb-tw__item--item-1, .kb-tw-cur--item-2 .kb-tw__item--item-2, .kb-tw-cur--item-3 .kb-tw__item--item-3 { outline: 2px solid #BFD9F2; outline-offset: 2px; background: #FAF7F2; }
</style>

react

export function KeyboardNavigation({
  orientation = "horizontal",
  current = "item-1",
  accent = "#BFD9F2",
  showNumbers = true,
}) {
  const items = [
    { id: "item-1", n: 1, label: "Overview" },
    { id: "item-2", n: 2, label: "Reports" },
    { id: "item-3", n: 3, label: "Settings" },
  ];
  return (
    <div style={{ width: 320, fontFamily: "system-ui, sans-serif", fontSize: 14, color: "#241430" }}>
      <div style={{ display: "flex", flexDirection: orientation === "vertical" ? "column" : "row", gap: 8 }}>
        {items.map((it) => (
          <a key={it.id} href="#" style={{
            display: "flex", alignItems: "center", gap: 6, padding: "9px 14px", borderRadius: 8,
            border: "1.5px solid #24143022", textDecoration: "none", color: "#241430",
            ...(current === it.id ? { outline: "2px solid " + accent, outlineOffset: 2, background: "#FAF7F2" } : {}),
          }}>
            {showNumbers && <span style={{ width: 16, height: 16, borderRadius: "50%", background: "#24143014", fontSize: 10, display: "grid", placeItems: "center", fontWeight: 700 }}>{it.n}</span>}
            {it.label}
          </a>
        ))}
      </div>
      <p style={{ marginTop: 12, fontSize: 12, color: "#241430aa" }}>{orientation === "vertical" ? "\u2193" : "\u2192"} arrow keys move focus &middot; current item ring shows focus</p>
    </div>
  );
}