This commit is contained in:
tresabhi committed 2026-10-27 16:49:52 -05:00
1 parent f10065887d
commit 10f8fa28f9
11 files changed
+121 -81

No files matched your search

@@ -30,22 +30,38 @@
font-size: 2em; font-size: 2em;
} }
&[data-list-child="true"]:not(:first-child), &[data-list-child="horizontal"]:not(:first-child),
*:not(:first-child) > &[data-parent-list-child="true"] { *:not(:first-child) > &[data-parent-list-child="horizontal"] {
border-top-left-radius: 0; border-top-left-radius: 0;
border-bottom-left-radius: 0; border-bottom-left-radius: 0;
border-left-width: var(--space-0); border-left-width: var(--space-0);
} }
&[data-list-child="true"]:not(:last-child), &[data-list-child="horizontal"]:not(:last-child),
*:not(:last-child) > &[data-parent-list-child="true"] { *:not(:last-child) > &[data-parent-list-child="horizontal"] {
border-top-right-radius: 0; border-top-right-radius: 0;
border-bottom-right-radius: 0; border-bottom-right-radius: 0;
border-right-width: var(--space-0); border-right-width: var(--space-0);
} }
&[data-list-child="vertical"]:not(:first-child),
*:not(:first-child) > &[data-parent-list-child="vertical"] {
border-top-left-radius: 0;
border-top-right-radius: 0;
border-top-width: var(--space-0);
}
&[data-list-child="vertical"]:not(:last-child),
*:not(:last-child) > &[data-parent-list-child="vertical"] {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
border-bottom-width: var(--space-0);
}
svg, svg,
img { img {
width: 1em; width: 1em;
@@ -60,6 +76,10 @@
&[data-variant="solid"] { &[data-variant="solid"] {
background-color: var(--accent-8); background-color: var(--accent-8);
&[data-high-contrast="true"] {
background-color: var(--accent-12);
}
} }
&[data-variant="surface"], &[data-variant="surface"],
@@ -10,8 +10,8 @@ export interface ButtonProps extends ComponentProps<"button"> {
size?: "regular" | "minor" | "major"; size?: "regular" | "minor" | "major";
highContrast?: boolean; highContrast?: boolean;
listChild?: boolean; listChild?: "horizontal" | "vertical";
parentListChild?: boolean; parentListChild?: "horizontal" | "vertical";
} }
export const LIGHT_TEXT_COLORS = new Set<Color>([ export const LIGHT_TEXT_COLORS = new Set<Color>([
@@ -1,44 +0,0 @@
import { Flex, IconButton, type FlexProps } from "@radix-ui/themes";
import type { ComponentProps, CSSProperties } from "react";
type SidebarIconButtonProps = ComponentProps<typeof IconButton> & {
selected: boolean;
src: string;
alt: string;
imageStyle?: CSSProperties;
};
export function SidebarIconGroup({ style, ...props }: FlexProps) {
return (
<Flex
direction="column"
overflow="hidden"
style={{ borderRadius: "var(--radius-full)", ...style }}
{...props}
/>
);
}
export function SidebarIconButton({
selected,
src,
alt,
imageStyle,
...props
}: SidebarIconButtonProps) {
return (
<IconButton
color={selected ? undefined : "gray"}
variant="soft"
size={{ initial: "2", sm: "3" }}
radius="none"
{...props}
>
<img
alt={alt}
src={src}
style={{ width: "50%", height: "50%", ...imageStyle }}
/>
</IconButton>
);
}
@@ -42,15 +42,15 @@ import { ModuleButton } from "../../../../ModuleButtons/ModuleButton";
import { ScreenshotButton } from "../../../../ScreenshotButton"; import { ScreenshotButton } from "../../../../ScreenshotButton";
import { SmallTankIcon } from "../../../../SmallTankIcon"; import { SmallTankIcon } from "../../../../SmallTankIcon";
import type { ThicknessRange } from "../../../../StaticArmor"; import type { ThicknessRange } from "../../../../StaticArmor";
import {
SidebarIconButton,
SidebarIconGroup,
} from "../../../../TankopediaSidebarIconButtons";
import { SkinSwitcher } from "../../../../TankopediaSkinSwitcher"; import { SkinSwitcher } from "../../../../TankopediaSkinSwitcher";
import { TankSearch } from "../../../../TankSearch"; import { TankSearch } from "../../../../TankSearch";
import { CustomShellButton } from "./components/CustomShellButton"; import { CustomShellButton } from "./components/CustomShellButton";
import { DynamicArmorSwitcher } from "./components/DynamicArmorSwitcher"; import { DynamicArmorSwitcher } from "./components/DynamicArmorSwitcher";
import { QuickInputs } from "./components/QuickInputs"; import { QuickInputs } from "./components/QuickInputs";
import {
SidebarIconButton,
SidebarIconGroup,
} from "./components/SidebarIconButton";
import { SpallLinerSwitcher } from "./components/SpallLinerSwitcher"; import { SpallLinerSwitcher } from "./components/SpallLinerSwitcher";
import { Thicknesses } from "./components/Thicknesses"; import { Thicknesses } from "./components/Thicknesses";
@@ -256,7 +256,7 @@ function Shells() {
radius="1" radius="1"
color={isSelected ? undefined : "gray"} color={isSelected ? undefined : "gray"}
variant={isSelected ? "surface" : "soft"} variant={isSelected ? "surface" : "soft"}
parentListChild parentListChild="horizontal"
onClick={() => { onClick={() => {
Tankopedia.mutate((draft) => { Tankopedia.mutate((draft) => {
draft.protagonist.shell = candidate.id; draft.protagonist.shell = candidate.id;
@@ -605,7 +605,7 @@ function EquipmentOption({
color={isSelected ? undefined : "gray"} color={isSelected ? undefined : "gray"}
variant={isSelected ? "surface" : "soft"} variant={isSelected ? "surface" : "soft"}
radius="1" radius="1"
parentListChild parentListChild="horizontal"
className={styles.slot} className={styles.slot}
onClick={() => { onClick={() => {
Tankopedia.mutate((draft) => { Tankopedia.mutate((draft) => {
@@ -0,0 +1,4 @@
.sidebar-icon-group {
display: flex;
flex-direction: column;
}
@@ -0,0 +1,43 @@
import type { ComponentProps } from "react";
import { classNames } from "../../ui/classNames";
import type { ButtonProps } from "../Button";
import { IconButton } from "../IconButton";
import styles from "./index.module.css";
type SidebarIconButtonProps = ButtonProps & {
selected: boolean;
src: string;
alt: string;
};
export function SidebarIconGroup({
className,
...props
}: ComponentProps<"div">) {
return (
<div
className={classNames(styles["sidebar-icon-group"], className)}
{...props}
/>
);
}
// TODO: sunset this
export function SidebarIconButton({
selected,
src,
alt,
...props
}: SidebarIconButtonProps) {
return (
<IconButton
parentListChild="vertical"
color={selected ? undefined : "gray"}
variant="soft"
size="major"
{...props}
>
<img alt={alt} src={src} />
</IconButton>
);
}
@@ -15,4 +15,8 @@
&[data-visible="true"] { &[data-visible="true"] {
transform: translate(0, -50%); transform: translate(0, -50%);
} }
.camouflage-icon {
border-radius: 50%;
}
} }
@@ -6,7 +6,7 @@ import { DuelModule, useDuel } from "../../hooks/useDuel";
import { useUnwrapper } from "../../hooks/useUnwrapper"; import { useUnwrapper } from "../../hooks/useUnwrapper";
import { Tankopedia } from "../../stores/tankopedia"; import { Tankopedia } from "../../stores/tankopedia";
import { TankopediaDisplay } from "../../stores/tankopediaPersistent/constants"; import { TankopediaDisplay } from "../../stores/tankopediaPersistent/constants";
import { SidebarIconButton } from "../Tankopedia/HeroSection/components/Options/components/SidebarIconButton"; import { IconButton } from "../IconButton";
import { Tooltip } from "../Tooltip"; import { Tooltip } from "../Tooltip";
import styles from "./index.module.css"; import styles from "./index.module.css";
@@ -35,30 +35,22 @@ export function TankopediaSkinSwitcher() {
className={styles["skin-switcher"]} className={styles["skin-switcher"]}
data-visible={disturbed && requestedDisplay === TankopediaDisplay.Model} data-visible={disturbed && requestedDisplay === TankopediaDisplay.Model}
> >
{skins.map((camouflage, index) => { {skins.map((camouflage) => {
const name = unwrap(camouflage.name!).replace( const name = unwrap(camouflage.name!).replace(
"%(camo_num)", "%(camo_num)",
SKIN_NUMBER, SKIN_NUMBER,
); );
const top = index === 0 ? "var(--radius-full)" : "0";
const bottom = index === skins.length - 1 ? "var(--radius-full)" : "0"; const selected = skin === camouflage.id;
return ( return (
<Tooltip key={camouflage.id} tooltip={name} side="left"> <Tooltip key={camouflage.id} tooltip={name} side="left">
<SidebarIconButton <IconButton
selected={skin === camouflage.id} parentListChild="vertical"
alt={name} color={selected ? undefined : "gray"}
src={alias("api", `/icons/camouflages/${camouflage.id}.webp`)} variant={selected ? "solid" : "soft"}
size={{ initial: "3", sm: "4" }} highContrast={selected}
radius="full" size="major"
style={{
borderRadius: `${top} ${top} ${bottom} ${bottom}`,
}}
imageStyle={{
width: "70%",
height: "70%",
borderRadius: "50%",
}}
onClick={() => { onClick={() => {
Tankopedia.mutate((draft) => { Tankopedia.mutate((draft) => {
draft.requestedSkin = draft.requestedSkin =
@@ -67,7 +59,13 @@ export function TankopediaSkinSwitcher() {
: camouflage.id; : camouflage.id;
}); });
}} }}
/> >
<img
className={styles["camouflage-icon"]}
alt={name}
src={alias("api", `/icons/camouflages/${camouflage.id}.webp`)}
/>
</IconButton>
</Tooltip> </Tooltip>
); );
})} })}
@@ -5,9 +5,6 @@
display: none; display: none;
position: absolute; position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
z-index: 1; z-index: 1;
background-color: var(--gray-12); background-color: var(--gray-12);
@@ -15,9 +12,24 @@
border-radius: var(--space-3); border-radius: var(--space-3);
padding: var(--space-2) var(--space-3); padding: var(--space-2) var(--space-3);
margin-bottom: var(--space-3);
white-space: nowrap; white-space: nowrap;
&[data-side="top"] {
bottom: 100%;
left: 50%;
transform: translateX(-50%);
margin-bottom: var(--space-3);
}
&[data-side="left"] {
top: 50%;
right: 100%;
transform: translateY(-50%);
margin-right: var(--space-3);
}
} }
&:hover { &:hover {
@@ -4,12 +4,15 @@ import styles from "./index.module.css";
interface Props { interface Props {
children: ReactNode; children: ReactNode;
tooltip: string; tooltip: string;
side?: "top" | "left";
} }
export function Tooltip({ children, tooltip }: Props) { export function Tooltip({ children, tooltip, side = "top" }: Props) {
return ( return (
<div className={styles.tooltip}> <div className={styles.tooltip}>
<div className={styles.text}>{tooltip}</div> <div className={styles.text} data-side={side}>
{tooltip}
</div>
{children} {children}
</div> </div>
); );