Handle BYE line visual

This commit is contained in:
Kalle (Sendou)
2021-12-24 12:24:40 +02:00
parent b586747038
commit 80b42eb7de
2 changed files with 72 additions and 12 deletions

View File

@@ -1,4 +1,5 @@
import classNames from "classnames";
import invariant from "tiny-invariant";
import type { BracketModified } from "~/services/tournament";
import { Unpacked } from "~/utils";
@@ -27,13 +28,44 @@ export function EliminationBracket({
status="UPCOMING"
/>
))}
{bracketSide.map((round, i) => {
{bracketSide.map((round, roundI) => {
const nextRound: Unpacked<BracketModified["winners"]> | undefined =
bracketSide[i + 1];
bracketSide[roundI + 1];
const amountOfMatchesBetweenRoundsEqual =
round.matches.length === nextRound?.matches.length;
const drawStraightLines =
round.matches.length === 1 || amountOfMatchesBetweenRoundsEqual;
const theKindOfLinesToDraw: (
| undefined
| "no-line"
| "bottom-only"
| "top-only"
)[] = new Array(
amountOfMatchesBetweenRoundsEqual
? round.matches.length
: Math.ceil(round.matches.length / 2)
)
.fill(null)
.map((_, lineI) => {
// lines 0 1 2 3
// rounds 0 1 2 3 4 5 6 7
if (roundI !== 0 || round.name.includes("Losers")) {
return undefined;
}
const matchOne = round.matches[lineI * 2];
const matchTwo = round.matches[lineI * 2 + 1];
invariant(matchOne, "matchOne is undefined");
invariant(matchTwo, "matchTwo is undefined");
if (
matchOne.participants?.includes(null) &&
matchTwo.participants?.includes(null)
) {
return "no-line";
}
if (matchOne.participants?.includes(null)) return "bottom-only";
return "top-only";
});
return (
<div
key={round.id}
@@ -51,18 +83,23 @@ export function EliminationBracket({
>
<div className="tournament-bracket__elim__matches">
{round.matches.map((match) => {
return <Match key={match.id} match={match} />;
// TODO: handle losers
return (
<Match
hidden={
roundI === 0 && match.participants?.includes(null)
}
key={match.id}
match={match}
/>
);
})}
</div>
<div className="tournament-bracket__elim__lines">
{i !== bracketSide.length - 1 &&
new Array(
amountOfMatchesBetweenRoundsEqual
? round.matches.length
: Math.ceil(round.matches.length / 2)
)
.fill(null)
.map((_, i) => <div key={i} />)}
{roundI !== bracketSide.length - 1 &&
theKindOfLinesToDraw.map((className, i) => (
<div className={className} key={i} />
))}
</div>
</div>
);
@@ -100,11 +137,13 @@ function RoundInfo({
export function Match({
match,
hidden,
}: {
match: Unpacked<Unpacked<BracketModified["winners"]>["matches"]>;
hidden?: boolean;
}) {
return (
<div className="tournament-bracket__elim__match">
<div className={classNames("tournament-bracket__elim__match", { hidden })}>
<div className="tournament-bracket__elim__roundNumber">
{match.number}
</div>

View File

@@ -63,6 +63,10 @@
row-gap: 2px;
}
.tournament-bracket__elim__match.hidden {
visibility: hidden;
}
.tournament-bracket__elim__roundNumber {
font-size: var(--fonts-xs);
grid-area: round-number;
@@ -111,6 +115,7 @@
}
.tournament-bracket__elim__lines > div {
position: relative;
width: calc(var(--brackets-match-height) / 4);
height: calc(
2px + var(--brackets-match-height) *
@@ -122,3 +127,19 @@
border-inline-end: 2px solid var(--theme-transparent);
border-radius: 0 var(--rounded) var(--rounded) 0;
}
.tournament-bracket__elim__lines > .bottom-only {
border-top: none;
border-radius: 0 0 var(--rounded) 0;
}
.bottom-only::after {
position: absolute;
top: 25%;
right: -4px;
width: 3px;
height: 60%;
background: var(--bg);
content: "";
transform: translate(-50%, -50%);
}