This commit is contained in:
Kalle 2026-01-05 19:01:50 +02:00
parent 6bcdb2c657
commit a44be81ad3
8 changed files with 161 additions and 79 deletions

1
.gitignore vendored
View File

@ -27,3 +27,4 @@ dump
/playwright/.cache/
notepad.txt
.vitest-attachments/

View File

@ -3,6 +3,17 @@
flex-direction: row;
}
.containerWithSideNav {
display: flex;
flex-direction: row;
width: 100%;
}
.mainWrapper {
flex: 1;
min-width: 0;
}
.main {
padding-block: var(--s-4) var(--s-32);
}

View File

@ -11,6 +11,7 @@ export const Main = ({
halfWidth,
bigger,
style,
sideNav,
}: {
children: React.ReactNode;
className?: string;
@ -18,6 +19,7 @@ export const Main = ({
halfWidth?: boolean;
bigger?: boolean;
style?: React.CSSProperties;
sideNav?: React.ReactNode;
}) => {
const error = useRouteError();
const isMinorSupporter = useHasRole("MINOR_SUPPORT");
@ -26,32 +28,41 @@ export const Main = ({
!isMinorSupporter &&
!isRouteErrorResponse(error);
return (
<div className={styles.container}>
<main
className={
classNameOverwrite
? clsx(classNameOverwrite, {
const mainElement = (
<main
className={
classNameOverwrite
? clsx(classNameOverwrite, {
[styles.narrow]: halfWidth,
"pt-8-forced": showLeaderboard,
})
: clsx(
styles.main,
styles.normal,
{
[styles.narrow]: halfWidth,
[styles.wide]: bigger,
"pt-8-forced": showLeaderboard,
})
: clsx(
styles.main,
styles.normal,
{
[styles.narrow]: halfWidth,
[styles.wide]: bigger,
"pt-8-forced": showLeaderboard,
},
className,
)
}
style={style}
>
{children}
</main>
</div>
},
className,
)
}
style={style}
>
{children}
</main>
);
if (sideNav) {
return (
<div className={styles.containerWithSideNav}>
{sideNav}
<div className={styles.mainWrapper}>{mainElement}</div>
</div>
);
}
return <div className={styles.container}>{mainElement}</div>;
};
export { styles as mainStyles };

View File

@ -0,0 +1,61 @@
.sideNav {
--side-nav-width: 200px;
background-color: var(--color-bg-high);
position: sticky;
left: 0;
top: var(--sticky-top);
display: flex;
flex-direction: column;
gap: var(--s-2);
overflow-y: auto;
max-height: calc(100vh - var(--layout-nav-height) - var(--s-5));
height: fit-content;
min-width: var(--side-nav-width);
max-width: var(--side-nav-width);
padding: var(--s-4) var(--s-2-5);
border: 1.5px solid var(--color-border);
border-radius: var(--rounded);
margin: var(--s-2-5);
&::-webkit-scrollbar,
&::-webkit-scrollbar-track {
background-color: transparent;
height: 18px;
width: 18px;
}
&::-webkit-scrollbar-thumb {
background-color: var(--color-text-accent-transparent);
border: 6px solid transparent;
border-radius: 99999px;
background-clip: content-box;
}
}
.sideNavLink {
font-size: var(--fonts-xs);
color: var(--color-text-high);
text-decoration: none;
padding: var(--s-1) var(--s-2);
border-radius: var(--rounded-xs);
transition:
background-color 0.15s,
color 0.15s;
&:hover {
color: var(--color-text);
background-color: var(--color-bg-higher);
}
&[aria-current="page"] {
color: var(--color-text);
background-color: var(--color-bg-higher);
font-weight: 600;
}
}
@media (max-width: 800px) {
.sideNav {
display: none;
}
}

View File

@ -0,0 +1,40 @@
import clsx from "clsx";
import type * as React from "react";
import styles from "./SideNav.module.css";
export function SideNav({
children,
className,
}: {
children: React.ReactNode;
className?: string;
}) {
return (
<nav className={clsx(styles.sideNav, "scrollbar", className)}>
{children}
</nav>
);
}
export function SideNavLink({
children,
href,
onClick,
isActive,
}: {
children: React.ReactNode;
href: string;
onClick?: (event: React.MouseEvent<HTMLAnchorElement>) => void;
isActive?: boolean;
}) {
return (
<a
href={href}
className={styles.sideNavLink}
onClick={onClick}
aria-current={isActive ? "page" : undefined}
>
{children}
</a>
);
}

View File

@ -24,41 +24,3 @@
.componentContent {
width: 100%;
}
.sideNav {
position: fixed;
left: var(--s-4);
top: 60px;
display: flex;
flex-direction: column;
gap: var(--s-1);
max-height: 90dvh;
overflow-y: auto;
z-index: 100;
@media (max-width: 1100px) {
display: none;
}
}
.sideNavLink {
font-size: var(--fonts-xs);
color: var(--color-text-high);
text-decoration: none;
padding: var(--s-1) var(--s-2);
border-radius: var(--rounded-xs);
transition:
background-color 0.15s,
color 0.15s;
&:hover {
color: var(--color-text);
background-color: var(--color-bg-high);
}
&[aria-current="page"] {
color: var(--color-text);
background-color: var(--color-bg-high);
font-weight: 600;
}
}

View File

@ -1,5 +1,4 @@
import { parseDate } from "@internationalized/date";
import clsx from "clsx";
import { useEffect, useState } from "react";
import { FormProvider, useForm } from "react-hook-form";
import { Ability } from "~/components/Ability";
@ -49,6 +48,7 @@ import { Pagination } from "~/components/Pagination";
import { Placement } from "~/components/Placement";
import { RelativeTime } from "~/components/RelativeTime";
import { Section } from "~/components/Section";
import { SideNav, SideNavLink } from "~/components/SideNav";
import { StageSelect } from "~/components/StageSelect";
import { SubmitButton } from "~/components/SubmitButton";
import { SubNav, SubNavLink } from "~/components/SubNav";
@ -107,19 +107,16 @@ export const SECTIONS = [
export default function ComponentsShowcasePage() {
return (
<>
<SideNav />
<Main className="stack lg">
<h1>Components</h1>
{SECTIONS.map(({ id, component: Component }) => (
<Component key={id} id={id} />
))}
</Main>
</>
<Main className="stack lg" sideNav={<ComponentsSideNav />}>
<h1>Components</h1>
{SECTIONS.map(({ id, component: Component }) => (
<Component key={id} id={id} />
))}
</Main>
);
}
function SideNav() {
function ComponentsSideNav() {
const [activeSection, setActiveSection] = useState<string | null>(null);
useEffect(() => {
@ -167,19 +164,18 @@ function SideNav() {
};
return (
<nav className={clsx(styles.sideNav, "scrollbar")}>
<SideNav>
{SECTIONS.map(({ title, id }) => (
<a
<SideNavLink
key={id}
href={`#${id}`}
className={styles.sideNavLink}
onClick={(e) => handleClick(e, id)}
aria-current={activeSection === id ? "page" : undefined}
isActive={activeSection === id}
>
{title}
</a>
</SideNavLink>
))}
</nav>
</SideNav>
);
}

View File

@ -30,6 +30,7 @@ import {
TierImage,
WeaponImage,
} from "~/components/Image";
import { mainStyles } from "~/components/Main";
import { Pagination } from "~/components/Pagination";
import { SubNav, SubNavLink } from "~/components/SubNav";
import { TopTenPlayer } from "~/features/leaderboards/components/TopTenPlayer";
@ -62,7 +63,6 @@ import {
} from "../loaders/u.$identifier.seasons.server";
import type { UserPageLoaderData } from "../loaders/u.$identifier.server";
import styles from "../user-page.module.css";
import { mainStyles } from "~/components/Main";
export { loader };
export const handle: SendouRouteHandle = {