From 4cdb71201366aeb76f73585715c4320098129964 Mon Sep 17 00:00:00 2001 From: GonnaHetzMe Date: Wed, 25 Mar 2026 11:18:53 +0100 Subject: [PATCH] feat: add CopyableCode component --- .../Armor/components/ArmorPlateDisplay.tsx | 29 ++--------- .../website/src/components/CopyableCode.tsx | 32 ++++++++++++ .../Tankopedia/MetaSection/index.tsx | 52 +++---------------- 3 files changed, 45 insertions(+), 68 deletions(-) create mode 100644 packages/website/src/components/CopyableCode.tsx diff --git a/packages/website/src/components/Armor/components/ArmorPlateDisplay.tsx b/packages/website/src/components/Armor/components/ArmorPlateDisplay.tsx index 87148680c..fb3fd4b6e 100644 --- a/packages/website/src/components/Armor/components/ArmorPlateDisplay.tsx +++ b/packages/website/src/components/Armor/components/ArmorPlateDisplay.tsx @@ -1,21 +1,19 @@ import { ReloadIcon } from "@radix-ui/react-icons"; import { Card, - Code, Flex, IconButton, Text, TextField, - Tooltip, } from "@radix-ui/themes"; import { Html } from "@react-three/drei"; -import { useRef, useState } from "react"; +import { useRef } from "react"; import { radToDeg } from "three/src/math/MathUtils.js"; import { resolveArmorIndex } from "../../../core/blitzkit/resolveArmorIndex"; -import { useLocale } from "../../../hooks/useLocale"; import { App } from "../../../stores/app"; import { Duel } from "../../../stores/duel"; import { Tankopedia } from "../../../stores/tankopedia"; +import { CopyableCode } from "../../CopyableCode"; import { layerTypeNames } from "./ShotDisplayCard"; import { ArmorType } from "./SpacedArmorScene"; @@ -23,8 +21,6 @@ export function ArmorPlateDisplay() { const highlightArmor = Tankopedia.use((state) => state.highlightArmor); const developerMode = App.useDeferred((state) => state.developerMode, false); const input = useRef(null); - const { strings } = useLocale(); - const [copied, setCopied] = useState(false); if (highlightArmor === undefined) return null; @@ -65,24 +61,9 @@ export function ArmorPlateDisplay() { <> DEV:{" "} - - { - navigator.clipboard.writeText(highlightArmor.name); - setCopied(true); - }} - onPointerLeave={() => setCopied(false)} - > - {highlightArmor.name} - - + + {highlightArmor.name} + )} diff --git a/packages/website/src/components/CopyableCode.tsx b/packages/website/src/components/CopyableCode.tsx new file mode 100644 index 000000000..8877b4b07 --- /dev/null +++ b/packages/website/src/components/CopyableCode.tsx @@ -0,0 +1,32 @@ +import { Code, Tooltip } from "@radix-ui/themes"; +import { useState, type ReactNode } from "react"; +import { useLocale } from "../hooks/useLocale"; + +interface CopyableCodeProps { + copy?: string; + children: ReactNode; +} + +export function CopyableCode({ copy, children }: CopyableCodeProps) { + const [copied, setCopied] = useState(false); + const { strings } = useLocale(); + + return ( + + { + if (!copy) return; + navigator.clipboard.writeText(copy); + setCopied(true); + }} + onPointerLeave={() => setCopied(false)} + > + {children} + + + ); +} diff --git a/packages/website/src/components/Tankopedia/MetaSection/index.tsx b/packages/website/src/components/Tankopedia/MetaSection/index.tsx index 787a0b069..f3276136a 100644 --- a/packages/website/src/components/Tankopedia/MetaSection/index.tsx +++ b/packages/website/src/components/Tankopedia/MetaSection/index.tsx @@ -4,13 +4,13 @@ import { TankType, TIER_ROMAN_NUMERALS, } from '@blitzkit/core'; -import { Box, Code, Flex, Tooltip } from '@radix-ui/themes'; -import { useState } from 'react'; +import { Box, Flex } from '@radix-ui/themes'; import { Var } from '../../../core/radix/var'; import { useLocale } from '../../../hooks/useLocale'; import { App } from '../../../stores/app'; import { Duel } from '../../../stores/duel'; import { classIcons } from '../../ClassIcon'; +import { CopyableCode } from '../../CopyableCode'; import { Listing } from './components/Listing'; const NATIONAL_BANNER_POSITION_OVERRIDES: Record = { @@ -24,7 +24,6 @@ export function MetaSection() { const protagonist = Duel.use((state) => state.protagonist.tank); const ClassIcon = classIcons[protagonist.class]; const { locale, strings } = useLocale(); - const [copied, setCopied] = useState(null); return ( @@ -103,53 +102,18 @@ export function MetaSection() { - - { - navigator.clipboard.writeText(`${protagonist.id}`); - setCopied('id'); - }} - onPointerLeave={() => { - if (copied === 'id') setCopied(null); - }} - > - {protagonist.id} - - + + {protagonist.id} + )} {developerMode && ( - - { - if (!protagonist.dev_name) return; - navigator.clipboard.writeText(protagonist.dev_name); - setCopied('name'); - }} - onPointerLeave={() => { - if (copied === 'name') setCopied(null); - }} - > - {protagonist.dev_name ?? '-'} - - + + {protagonist.dev_name ?? '-'} + )} {protagonist.type === TankType.PREMIUM && (