sendou.ink/app/components/NewTabs.tsx
Kalle 7dec8c572e
SendouQ Season 2 changes (#1542)
* Initial

* Saves preferences

* Include TW

* mapModePreferencesToModeList

* mapPoolFromPreferences initial

* Preference to map pool

* Adjust seed

* q.looking tests

* adds about created map preferences to memento in the correct spot (two preferrers)

* Failing test about modes

* Mode preferences to memento

* Remove old Plus Voting code

* Fix seeding

* find match by id via kysely

* View map memento

* Fix up map list generation logic

* Mode memento info

* Future match modes

* Add TODO

* Migration number

* Migrate test DB

* Remove old map pool code

* createGroupFromPrevious new

* Settings styling

* VC to settings

* Weapon pool

* Add TODOs

* Progress

* Adjust mode exclusion policy

* Progress

* Progress

* Progress

* Notes in progress

* Note feedback after submit

* Textarea styling

* Unskip tests

* Note sorting failing test

* Private note in Q

* Ownerpicksmaps later

* New bottom section

* Mobile layout initial

* Add basic match meta

* Tabs initial

* Sticky tab

* Unseen messages in match page

* Front page i18n

* Settings i18n

* Looking 18n

* Chat i18n

* Progress

* Tranfer weapon pools script

* Sticky on match page

* Match page translations

* i18n - tiers page

* Preparing page i18n

* Icon

* Show add note right after report
2023-11-30 20:57:06 +02:00

133 lines
3.5 KiB
TypeScript

import { Tab } from "@headlessui/react";
import clsx from "clsx";
import * as React from "react";
interface NewTabsProps {
tabs: {
label: string;
number?: number;
hidden?: boolean;
}[];
content: {
key: string;
element: React.ReactNode;
hidden?: boolean;
}[];
scrolling?: boolean;
selectedIndex?: number;
setSelectedIndex?: (index: number) => void;
/** Don't take space when no tabs to show? */
disappearing?: boolean;
type?: "divider";
sticky?: boolean;
}
export function NewTabs(args: NewTabsProps) {
if (args.type === "divider") {
return <DividerTabs {...args} />;
}
const {
tabs,
content,
scrolling = true,
selectedIndex,
setSelectedIndex,
disappearing = false,
} = args;
const cantSwitchTabs = tabs.filter((t) => !t.hidden).length <= 1;
return (
<Tab.Group selectedIndex={selectedIndex} onChange={setSelectedIndex}>
<Tab.List
className={clsx("tab__buttons-container", {
"overflow-x-auto": scrolling,
invisible: cantSwitchTabs && !disappearing,
hidden: cantSwitchTabs && disappearing,
"tab__buttons-container__sticky": args.sticky,
})}
>
{tabs
.filter((t) => !t.hidden)
.map((tab) => {
return (
<Tab
key={tab.label}
className="tab__button"
data-testid={`tab-${tab.label}`}
>
{tab.label}
{typeof tab.number === "number" && tab.number !== 0 && (
<span className="tab__number">{tab.number}</span>
)}
</Tab>
);
})}
</Tab.List>
<Tab.Panels
className={clsx({ "mt-4": !cantSwitchTabs || !disappearing })}
>
{content
.filter((c) => !c.hidden)
.map((c) => {
return <Tab.Panel key={c.key}>{c.element}</Tab.Panel>;
})}
</Tab.Panels>
</Tab.Group>
);
}
function DividerTabs({
tabs,
content,
scrolling = true,
selectedIndex,
setSelectedIndex,
disappearing = false,
}: NewTabsProps) {
const cantSwitchTabs = tabs.filter((t) => !t.hidden).length <= 1;
return (
<Tab.Group selectedIndex={selectedIndex} onChange={setSelectedIndex}>
<Tab.List
className={clsx("divider-tab__buttons-container", {
"overflow-x-auto": scrolling,
invisible: cantSwitchTabs && !disappearing,
hidden: cantSwitchTabs && disappearing,
})}
>
{tabs
.filter((t) => !t.hidden)
.map((tab, i) => {
return (
<React.Fragment key={tab.label}>
<Tab
className="divider-tab__button"
data-testid={`tab-${tab.label}`}
>
{tab.label}
{typeof tab.number === "number" && tab.number !== 0 && (
<span className="ml-1">({tab.number})</span>
)}
</Tab>
{i !== tabs.length - 1 && (
<div className="divider-tab__line-guy" />
)}
</React.Fragment>
);
})}
</Tab.List>
<Tab.Panels
className={clsx({ "mt-4": !cantSwitchTabs || !disappearing })}
>
{content
.filter((c) => !c.hidden)
.map((c) => {
return <Tab.Panel key={c.key}>{c.element}</Tab.Panel>;
})}
</Tab.Panels>
</Tab.Group>
);
}