From aa982d73decc474789cd1975e74ad7d19031ba67 Mon Sep 17 00:00:00 2001
From: tresabhi <43380238+tresabhi@users.noreply.github.com>
Date: Mon, 9 Nov 2026 23:05:19 -0600
Subject: [PATCH] thicknesses
---
.../components/Thicknesses.tsx | 204 ------------------
.../components/TankopediaSandbox/index.tsx | 2 +
.../components/Thicknesses/index.module.css | 67 ++++++
.../src/components/Thicknesses/index.tsx | 131 +++++++++++
4 files changed, 200 insertions(+), 204 deletions(-)
delete mode 100644 packages/website/src/components/TankopediaOptions/components/Thicknesses.tsx
create mode 100644 packages/website/src/components/Thicknesses/index.module.css
create mode 100644 packages/website/src/components/Thicknesses/index.tsx
diff --git a/packages/website/src/components/TankopediaOptions/components/Thicknesses.tsx b/packages/website/src/components/TankopediaOptions/components/Thicknesses.tsx
deleted file mode 100644
index 8e908a031..000000000
--- a/packages/website/src/components/TankopediaOptions/components/Thicknesses.tsx
+++ /dev/null
@@ -1,204 +0,0 @@
-import { literals } from "@blitzkit/i18n/src/literals";
-import { EyeClosedIcon, EyeOpenIcon, ReloadIcon } from "@radix-ui/react-icons";
-import { Button, Checkbox, Flex, Text } from "@radix-ui/themes";
-import { Suspense } from "react";
-import { useLocale } from "../../../hooks/useLocale";
-import { Tankopedia } from "../../../stores/tankopedia";
-import { TankopediaPersistent } from "../../../stores/tankopediaPersistent";
-import { TankopediaDisplay } from "../../../stores/tankopediaPersistent/constants";
-import type { MaybeSkeletonComponentProps } from "../../../types/maybeSkeletonComponentProps";
-import type { ThicknessRange } from "../../TankStaticArmor";
-import { DynamicArmorSwitcher } from "./DynamicArmorSwitcher";
-
-type ThicknessesProps = MaybeSkeletonComponentProps & {
- thicknessRange: ThicknessRange;
-};
-
-export function Thicknesses({ thicknessRange, skeleton }: ThicknessesProps) {
- const display = Tankopedia.use((state) => state.display);
- const showExternalModules = TankopediaPersistent.use(
- (state) => state.showExternalModules,
- );
- const showSpacedArmor = TankopediaPersistent.use(
- (state) => state.showSpacedArmor,
- );
- const showPrimaryArmor = TankopediaPersistent.use(
- (state) => state.showPrimaryArmor,
- );
- const editStatic = Tankopedia.use((state) => state.editStatic);
- const { strings } = useLocale();
-
- return (
-
-
- {
- TankopediaPersistent.mutate((draft) => {
- draft.showPrimaryArmor = !draft.showPrimaryArmor;
- });
- Tankopedia.mutate((draft) => {
- draft.highlightArmor = undefined;
- });
- }}
- >
-
-
- {literals(strings.common.units.mm, {
- value: (thicknessRange.value * 1.5).toFixed(0),
- })}
-
-
- {strings.website.tools.tankopedia.sandbox.static.primary}
-
-
- {literals(strings.common.units.mm, { value: 0 })}
-
-
-
-
- {showPrimaryArmor ? : }
-
-
-
- {
- TankopediaPersistent.mutate((draft) => {
- draft.showSpacedArmor = !draft.showSpacedArmor;
- });
- Tankopedia.mutate((draft) => {
- draft.highlightArmor = undefined;
- });
- }}
- >
-
-
- {literals(strings.common.units.mm, {
- value: thicknessRange.value.toFixed(0),
- })}
-
-
- {strings.website.tools.tankopedia.sandbox.static.spaced}
-
-
- {literals(strings.common.units.mm, { value: 0 })}
-
-
-
-
- {showSpacedArmor ? : }
-
-
-
- {
- TankopediaPersistent.mutate((draft) => {
- draft.showExternalModules = !draft.showExternalModules;
- });
- Tankopedia.mutate((draft) => {
- draft.highlightArmor = undefined;
- });
- }}
- >
-
-
- {strings.website.tools.tankopedia.sandbox.static.external}
-
-
-
-
- {showExternalModules ? : }
-
-
-
-
-
-
- {
- Tankopedia.mutate((draft) => {
- draft.editStatic = !draft.editStatic;
- draft.highlightArmor = undefined;
- });
- }}
- >
-
- {strings.website.tools.tankopedia.sandbox.static.edit.label}
-
-
-
-
-
-
-
-
- {!skeleton && (
-
-
-
- )}
-
- );
-}
diff --git a/packages/website/src/components/TankopediaSandbox/index.tsx b/packages/website/src/components/TankopediaSandbox/index.tsx
index d050106c1..6b18245e9 100644
--- a/packages/website/src/components/TankopediaSandbox/index.tsx
+++ b/packages/website/src/components/TankopediaSandbox/index.tsx
@@ -26,6 +26,7 @@ import { TankopediaOptions } from "../TankopediaOptions";
import { TankopediaSkinSwitcher } from "../TankopediaSkinSwitcher";
import { TankSandboxLoader } from "../TankSandboxLoader";
import { TankStaticArmor, type ThicknessRange } from "../TankStaticArmor";
+import { Thicknesses } from "../Thicknesses";
import styles from "./index.module.css";
type TankSandboxProps = MaybeSkeletonComponentProps & {
@@ -176,6 +177,7 @@ export function TankopediaSandbox({
+
diff --git a/packages/website/src/components/Thicknesses/index.module.css b/packages/website/src/components/Thicknesses/index.module.css
new file mode 100644
index 000000000..11d885958
--- /dev/null
+++ b/packages/website/src/components/Thicknesses/index.module.css
@@ -0,0 +1,67 @@
+.thicknesses {
+ pointer-events: auto;
+
+ display: flex;
+ flex-direction: column;
+ align-items: flex-end;
+ gap: var(--space-4);
+
+ position: absolute;
+ right: var(--space-4);
+ top: 50%;
+
+ user-select: none;
+ transition: var(--duration-brief);
+
+ /* slides off the right edge when the static armor view isn't active */
+ transform: translate(calc(100% + var(--space-4)), -50%);
+
+ &[data-visible="true"] {
+ transform: translate(0, -50%);
+ }
+}
+
+.toggle {
+ display: flex;
+ gap: var(--space-3);
+
+ padding: 0;
+ border: none;
+ background: none;
+ font: inherit;
+
+ cursor: pointer;
+ opacity: 0.5;
+
+ &[data-visible="true"] {
+ opacity: 1;
+ }
+
+ &[data-scaled="true"] {
+ height: 4rem;
+ }
+}
+
+.labels {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-end;
+ justify-content: space-between;
+}
+
+.swatch {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ width: 1rem;
+ border-radius: var(--radius-max);
+ overflow: hidden;
+
+ color: black;
+
+ /* the unscaled swatch is just an icon-sized dot */
+ .toggle:not([data-scaled="true"]) & {
+ height: 1rem;
+ }
+}
diff --git a/packages/website/src/components/Thicknesses/index.tsx b/packages/website/src/components/Thicknesses/index.tsx
new file mode 100644
index 000000000..fa2bcd12f
--- /dev/null
+++ b/packages/website/src/components/Thicknesses/index.tsx
@@ -0,0 +1,131 @@
+import { literals } from "@blitzkit/i18n/src/literals";
+import { EyeClosedIcon, EyeOpenIcon } from "@radix-ui/react-icons";
+import { useCallback, type ReactNode } from "react";
+import { useStrings } from "../../hooks/useStrings";
+import { Tankopedia } from "../../stores/tankopedia";
+import { TankopediaPersistent } from "../../stores/tankopediaPersistent";
+import { TankopediaDisplay } from "../../stores/tankopediaPersistent/constants";
+import type { ThicknessRange } from "../TankStaticArmor";
+import { Text } from "../Text";
+import styles from "./index.module.css";
+
+interface LayerToggleProps {
+ visible: boolean;
+ label: ReactNode;
+ /** Thickness labels for the top and bottom of the scale */
+ range?: [ReactNode, ReactNode];
+ swatch: string;
+ onToggle(): void;
+}
+
+function LayerToggle({
+ visible,
+ label,
+ range,
+ swatch,
+ onToggle,
+}: LayerToggleProps) {
+ return (
+
+ );
+}
+
+export interface ThicknessesProps {
+ thicknessRange: ThicknessRange;
+}
+
+export function Thicknesses({ thicknessRange }: ThicknessesProps) {
+ const strings = useStrings();
+ const display = Tankopedia.use((state) => state.loaders.display.loaded);
+ const showControls = Tankopedia.use((state) => state.showControls);
+ const showPrimaryArmor = TankopediaPersistent.use(
+ (state) => state.showPrimaryArmor,
+ );
+ const showSpacedArmor = TankopediaPersistent.use(
+ (state) => state.showSpacedArmor,
+ );
+ const showExternalModules = TankopediaPersistent.use(
+ (state) => state.showExternalModules,
+ );
+ const { element } = strings.tanks.shot_card;
+ const mm = useCallback(
+ (value: number) =>
+ literals(strings.common.units.mm, { value: value.toFixed(0) }),
+ [strings],
+ );
+ const clearHighlight = useCallback(() => {
+ Tankopedia.mutate((draft) => {
+ draft.highlightArmor = undefined;
+ });
+ }, []);
+
+ return (
+
+ {
+ TankopediaPersistent.mutate((draft) => {
+ draft.showPrimaryArmor = !draft.showPrimaryArmor;
+ });
+ clearHighlight();
+ }}
+ />
+
+ {
+ TankopediaPersistent.mutate((draft) => {
+ draft.showSpacedArmor = !draft.showSpacedArmor;
+ });
+ clearHighlight();
+ }}
+ />
+
+ {
+ TankopediaPersistent.mutate((draft) => {
+ draft.showExternalModules = !draft.showExternalModules;
+ });
+ clearHighlight();
+ }}
+ />
+
+ );
+}