Skip to content

feat: add knockout wheel fixture - #123

Merged
starc007 merged 3 commits into
starc007:mainfrom
chakravartiavinit:feat/knockout-wheel
Jul 27, 2026
Merged

feat: add knockout wheel fixture#123
starc007 merged 3 commits into
starc007:mainfrom
chakravartiavinit:feat/knockout-wheel

Conversation

@chakravartiavinit

Copy link
Copy Markdown
Contributor

Adds Knockout Wheel, the second version on the Fixtures page: the same tournament tree wrapped around its champion.

Stacked on #122, which introduces the versioned Fixtures page this entry slots into. Review that one first; this branch contains only the wheel.

What it looks like

Tournament decided Played through the Round of 16
Champion holds the hub under a trophy and a warm halo, and their run from the rim inward stays lit while everyone else recedes. Undecided slots draw the same shield the bracket uses for a TBD side. No champion, so no trophy, no halo, and nothing dims.

The geometry

The hub is the final. Each round becomes a ring further out, and the teams themselves form the rim, so a 32-team draw is 63 nodes across 5 rings. Every parent splits its angular wedge between its two feeders, halving each level, with a small gap pulling siblings toward their parent so subtrees separate visually. Sibling pairs are joined by an arc at the midpoint radius plus a radial stem to the parent; the hub's two feeders sit opposite each other and get plain radial lines, since an arc between them would be a half circle.

Nothing is hard-coded to a bracket size. rounds.length drives the ring count and radii, so 8, 16 or 32 teams all render without special cases.

Interaction

  • Hover a flag for a Tooltip with Round · Teams · Score, and that flag alone stays lit.
  • Tap on touch pins the same trace with a label anchored to the flag, since Tooltip is pointer-only by design. Tap again to release.
  • Keyboard: one tab stop for the wheel, then arrows follow the geometry — up walks toward the hub, down to a feeder, left/right around the ring.
  • At rest the champion's path is lit.

Props

  • rounds — outermost round first, each holding half as many matches as the one before.
  • initialRound — index of the outermost round to draw. Earlier rounds are dropped and the kept round's own teams become the rim, so 2 on a 32-team draw opens at the quarter-finals. Defaults to the whole tree.

The Match / Round types are a local copy of the bracket's rather than an import: importing would make the registry bundle the entire bracket into @beui/knockout-wheel. They stay structurally compatible, so one tournament object feeds both components.

Accessibility

role="img" prunes the svg's descendants, so every result is restated in an sr-only list of named lists — deliberately not <section aria-label>, which would add five landmarks competing with real page navigation. Focus uses ring-foreground rather than the --ring token, which is a 10% white hairline that disappears over a flag.

Notes for review

Two things worth knowing about, both verified rather than assumed:

  • Hydration. Math.sin / Math.cos are implementation-defined in their last digits, so Bun's SSR and the browser disagreed on every derived coordinate and React reported a mismatch on each one. polar() now quantizes to 3 decimals, far below sub-pixel at a 760-unit viewBox.
  • Flag loading. SVG <image> has no loading="lazy", so 63 requests fired on mount. They're now gated behind useInView: 0 requests off-screen, 63 once the wheel approaches the viewport.

Below 32rem the wheel holds its size and pans inside its own scroll container, the same pattern KnockoutBracket uses — letting it shrink put 32 rim flags at 21px, too small to tell apart or tap.

Checks

bun run check (typecheck, lint, registry) and bun test pass — 41 tests, 53 registry components. Verified in the browser across pointer, touch and keyboard, in both themes, and under prefers-reduced-motion.

@starc007
starc007 merged commit a94f504 into starc007:main Jul 27, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants