72 lines
2.3 KiB
TypeScript
72 lines
2.3 KiB
TypeScript
|
|
"use client"
|
||
|
|
|
||
|
|
import type { LucideIcon } from "lucide-react"
|
||
|
|
import type { ReactNode } from "react"
|
||
|
|
import { cn } from "@/lib/utils"
|
||
|
|
|
||
|
|
export type SetupStep = {
|
||
|
|
key: string
|
||
|
|
label: string
|
||
|
|
icon: LucideIcon
|
||
|
|
}
|
||
|
|
|
||
|
|
export type TournamentSetupNavProps = {
|
||
|
|
steps: SetupStep[]
|
||
|
|
activeStep: string
|
||
|
|
onChange: (key: string) => void
|
||
|
|
children?: ReactNode
|
||
|
|
}
|
||
|
|
|
||
|
|
export function TournamentSetupNav({
|
||
|
|
steps,
|
||
|
|
activeStep,
|
||
|
|
onChange,
|
||
|
|
children,
|
||
|
|
}: TournamentSetupNavProps) {
|
||
|
|
return (
|
||
|
|
<div className="flex flex-col gap-6">
|
||
|
|
<nav aria-label="Turneringsoppsett-steg">
|
||
|
|
{/*
|
||
|
|
Every step is always selectable in any order — no gating, no completion
|
||
|
|
checkmarks, no step numbers. On wide screens all 6 pills share the row
|
||
|
|
equally; on narrow screens the row scrolls sideways rather than wrapping
|
||
|
|
or collapsing, so every labelled step stays reachable.
|
||
|
|
*/}
|
||
|
|
<div
|
||
|
|
role="tablist"
|
||
|
|
aria-orientation="horizontal"
|
||
|
|
className="flex snap-x snap-mandatory gap-2 overflow-x-auto pb-1 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden"
|
||
|
|
>
|
||
|
|
{steps.map((step) => {
|
||
|
|
const Icon = step.icon
|
||
|
|
const isActive = step.key === activeStep
|
||
|
|
return (
|
||
|
|
<button
|
||
|
|
key={step.key}
|
||
|
|
type="button"
|
||
|
|
role="tab"
|
||
|
|
aria-selected={isActive}
|
||
|
|
onClick={() => onChange(step.key)}
|
||
|
|
className={cn(
|
||
|
|
"flex min-h-11 flex-1 shrink-0 snap-start items-center justify-center gap-2 rounded-2xl px-4 py-2.5",
|
||
|
|
"whitespace-nowrap text-sm font-bold transition-all duration-200 ease-in-out",
|
||
|
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
||
|
|
"active:scale-[0.98]",
|
||
|
|
isActive
|
||
|
|
? "bg-primary text-primary-foreground shadow-md shadow-black/8"
|
||
|
|
: "border border-border bg-card text-foreground hover:bg-accent/50",
|
||
|
|
)}
|
||
|
|
>
|
||
|
|
<Icon aria-hidden="true" className="size-5 shrink-0" />
|
||
|
|
<span>{step.label}</span>
|
||
|
|
</button>
|
||
|
|
)
|
||
|
|
})}
|
||
|
|
</div>
|
||
|
|
</nav>
|
||
|
|
|
||
|
|
<div>{children}</div>
|
||
|
|
</div>
|
||
|
|
)
|
||
|
|
}
|