Fixtures Knockout Wheel
beui/knockout-wheelFreeBlock
The tournament drawn radially. The champion holds the hub, each round is a ring further out, and the teams themselves form the rim. Nodes spring in ring by ring, and hovering one isolates that team while the rest recede. Teams show a flag, a logo or their initials, and a deeper draw grows another ring.
Install it
npx shadcn@latest add https://beui.dev/r/knockout-wheel.jsonSource
1"use client";2// beui.dev/components/blocks/knockout-bracket34import { Shield } from "lucide-react";5import { motion, useInView, useReducedMotion } from "motion/react";6import {7 type KeyboardEvent,8 memo,9 useCallback,10 useId,11 useMemo,12 useRef,13 useState,14} from "react";15import { Tooltip } from "@/components/motion/tooltip";16import { SPRING_PANEL } from "@/lib/ease";17import { useHoverCapable } from "@/lib/hooks/use-hover-capable";18import { cn } from "@/lib/utils";1920export type Team = {21 name: string;22 /**23 * Any square image URL — club crest, org mark, player photo. Wins over `code`.24 * Drawn as-is on the node's card-colored disc, so a transparent-background25 * mark inked for one theme disappears in the other: ship artwork that reads on26 * both, or pick the URL yourself from your theme state.27 */28 logo?: string;29 /** ISO 3166-1 alpha-2 code, loaded from flagcdn.com (England is gb-eng). Used when `logo` is absent. */30 code?: string;31};3233export type MatchSide = {34 team: Team | null;35 score: number | null;36 /** Present on both sides to render shootout scores — 1 (3). */37 penalties?: number | null;38};3940/** Structurally compatible with the knockout bracket's Match, minus the fields41 * the wheel never draws (date, time, status). */42export type Match = {43 id: string;44 home: MatchSide;45 away: MatchSide;46 winner?: "home" | "away";47};4849export type Round = {50 /** Read out with the match in tooltips and the screen-reader list. */51 name: string;52 matches: Match[];53};5455export interface KnockoutWheelProps {56 /**57 * The whole draw, ordered widest round first — the same array the knockout58 * bracket takes. Any single-elimination tournament fits: each round holds half59 * the matches of the one before it (16 → 8 → 4 → 2 → 1) and `rounds[r].matches[k]`60 * is fed by matches `2k` and `2k + 1` of the round before it. Two rounds are61 * enough; the wheel grows a ring per round and sizes itself to the rim.62 */63 rounds: Round[];64 /**65 * Index of the outermost round to draw. Earlier rounds are dropped and the66 * kept round's own teams become the rim, so `1` on a 32-team draw opens at the67 * Round of 16. Defaults to 0 (the whole tree); clamped to the valid range.68 */69 initialRound?: number;70 className?: string;71}7273const SIZE = 760;74const CENTER = SIZE / 2;75// Solid trophy glyph drawn in a 24-unit box.76const TROPHY_SIZE = 24;77const TROPHY_PATH =78// … truncated
What it pulls in
npm packages
Files it writes
More from beui
All 104 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| File Upload Attachment Uploadattachment-upload | beui | Blocks | Free | 4 deps · 5 files | |
| Availability Scheduleravailability-scheduler | beui | Blocks | Free | 4 deps · 15 files | |
| Bloom Menubloom-menu | beui | Blocks | Free | 4 deps · 3 files | |
| Command Palettecommand-palette | beui | Blocks | Free | 4 deps · 3 files | |
| Dynamic Islanddynamic-island | beui | Blocks | Free | 3 deps · 3 files | |
| Expandable Action Barexpandable-action-bar | beui | Blocks | Free | 3 deps · 2 files | |
| Expandable Tabsexpandable-tabs | beui | Blocks | Free | 3 deps · 3 files | |
| Feedback Widgetfeedback-widget | beui | Blocks | Free | 4 deps · 9 files |
