feat: code split module buttons

This commit is contained in:
TrèsAbhi committed 2024-02-12 19:24:34 -06:00
1 parent 9d7c60e92d
commit 574b1eec92
17 files changed
+230 -153

No files matched your search

@@ -10,7 +10,8 @@ import {
Tooltip,
} from '@radix-ui/themes';
import { useState } from 'react';
import { ModuleButton } from '../../../../../../components/ModuleButton';
import { ModuleButton } from '../../../../../../components/ModuleButtons/ModuleButton';
import { ShellButton } from '../../../../../../components/ModuleButtons/ShellButton';
import { SmallTankIcon } from '../../../../../../components/SmallTankIcon';
import { resolveNearPenetration } from '../../../../../../core/blitz/resolveNearPenetration';
import {
@@ -39,9 +40,8 @@ export function AntagonistBar() {
<Flex>
{antagonist.gun.shells.map((shell, index) => {
return (
<ModuleButton
<ShellButton
selected={antagonist.shell.id === shell.id}
type="shell"
shell={shell.icon}
rowChild
first={index === 0}
@@ -155,7 +155,6 @@ export function AntagonistBar() {
discriminator={
TIER_ROMAN_NUMERALS[turret.tier]
}
type="module"
module="turret"
/>
</Tooltip>
@@ -178,7 +177,6 @@ export function AntagonistBar() {
}}
selected={antagonist.gun.id === gun.id}
discriminator={TIER_ROMAN_NUMERALS[gun.tier]}
type="module"
module="gun"
/>
</Tooltip>
@@ -1,5 +1,5 @@
import { Heading } from '@radix-ui/themes';
import { ModuleButton } from '../../../../../../../components/ModuleButton';
import { CamouflageButton } from '../../../../../../../components/ModuleButtons/CamouflageButton';
import {
mutateTankopediaTemporary,
useTankopediaTemporary,
@@ -13,11 +13,10 @@ export function Camouflage() {
<ConfigurationChildWrapper>
<Heading size="4">Camouflage</Heading>
<ModuleButton
<CamouflageButton
selected={camouflage}
first
last
type="camouflage"
onClick={() => {
mutateTankopediaTemporary((draft) => {
draft.camouflage = !camouflage;
@@ -1,6 +1,6 @@
import { Flex, Heading } from '@radix-ui/themes';
import { use } from 'react';
import { ModuleButton } from '../../../../../../../components/ModuleButton';
import { ConsumableButton } from '../../../../../../../components/ModuleButtons/ConsumableButton';
import { checkConsumableProvisionInclusivity } from '../../../../../../../core/blitzkrieg/checkConsumableProvisionInclusivity';
import { consumableDefinitions } from '../../../../../../../core/blitzkrieg/consumableDefinitions';
import { useDuel } from '../../../../../../../stores/duel';
@@ -32,12 +32,11 @@ export function Consumables() {
const selected = consumables.includes(consumable.id);
return (
<ModuleButton
<ConsumableButton
key={consumable.id}
first={index === 0}
last={index === consumablesList.length - 1}
rowChild
type="consumable"
disabled={
protagonist.tank.consumables === consumables.length && !selected
}
@@ -1,6 +1,6 @@
import { Flex, Heading } from '@radix-ui/themes';
import { use } from 'react';
import { ModuleButton } from '../../../../../../../components/ModuleButton';
import { EquipmentButton } from '../../../../../../../components/ModuleButtons/EquipmentButton';
import { equipmentDefinitions } from '../../../../../../../core/blitzkrieg/equipmentDefinitions';
import { useDuel } from '../../../../../../../stores/duel';
import {
@@ -27,8 +27,7 @@ export function Equipments() {
<Flex gap="2" key={rowIndex}>
{equipmentRow.map((equipment, columnIndex) => (
<Flex key={columnIndex}>
<ModuleButton
type="equipment"
<EquipmentButton
equipment={equipment[0]}
first
rowChild
@@ -43,8 +42,7 @@ export function Equipments() {
});
}}
/>
<ModuleButton
type="equipment"
<EquipmentButton
equipment={equipment[1]}
last
rowChild
@@ -1,6 +1,10 @@
import { Flex, Heading } from '@radix-ui/themes';
import { ModuleButton } from '../../../../../../../components/ModuleButton';
import { TIER_ROMAN_NUMERALS } from '../../../../../../../core/blitzkrieg/tankDefinitions';
import { ModuleButton } from '../../../../../../../components/ModuleButtons/ModuleButton';
import { ShellButton } from '../../../../../../../components/ModuleButtons/ShellButton';
import {
SHELL_NAMES,
TIER_ROMAN_NUMERALS,
} from '../../../../../../../core/blitzkrieg/tankDefinitions';
import { mutateDuel, useDuel } from '../../../../../../../stores/duel';
import { ConfigurationChildWrapper } from './ConfigurationChildWrapper';
@@ -18,7 +22,6 @@ export function Modules() {
<ModuleButton
key={turret.id}
selected={protagonist.turret.id === turret.id}
type="module"
module="turret"
discriminator={TIER_ROMAN_NUMERALS[turret.tier]}
first={index === 0}
@@ -41,7 +44,6 @@ export function Modules() {
return (
<ModuleButton
key={gun.id}
type="module"
module="gun"
discriminator={TIER_ROMAN_NUMERALS[gun.tier]}
selected={protagonist.gun.id === gun.id}
@@ -64,7 +66,6 @@ export function Modules() {
return (
<ModuleButton
key={engine.id}
type="module"
module="engine"
discriminator={TIER_ROMAN_NUMERALS[engine.tier]}
selected={protagonist.engine.id === engine.id}
@@ -86,7 +87,6 @@ export function Modules() {
return (
<ModuleButton
key={track.id}
type="module"
module="chassis"
discriminator={TIER_ROMAN_NUMERALS[track.tier]}
selected={protagonist.track.id === track.id}
@@ -106,10 +106,10 @@ export function Modules() {
<Flex>
{protagonist.gun.shells.map((shell, index) => {
return (
<ModuleButton
<ShellButton
key={shell.id}
type="shell"
shell={shell.icon}
discriminator={SHELL_NAMES[shell.type]}
selected={protagonist.shell.id === shell.id}
first={index === 0}
last={index === protagonist.gun.shells.length - 1}
@@ -1,6 +1,6 @@
import { Flex, Heading } from '@radix-ui/themes';
import { use } from 'react';
import { ModuleButton } from '../../../../../../../components/ModuleButton';
import { ProvisionButton } from '../../../../../../../components/ModuleButtons/ProvisionButton';
import { checkConsumableProvisionInclusivity } from '../../../../../../../core/blitzkrieg/checkConsumableProvisionInclusivity';
import { provisionDefinitions } from '../../../../../../../core/blitzkrieg/provisionDefinitions';
import { useDuel } from '../../../../../../../stores/duel';
@@ -32,12 +32,11 @@ export function Provisions() {
const selected = provisions.includes(provision.id);
return (
<ModuleButton
<ProvisionButton
key={provision.id}
first={index === 0}
last={index === provisionsList.length - 1}
rowChild
type="provision"
disabled={
protagonist.tank.provisions === provisions.length && !selected
}
-118
View File
@@ -1,118 +0,0 @@
import { Button, Text } from '@radix-ui/themes';
import { CSSProperties, ComponentProps } from 'react';
import { asset } from '../core/blitzkrieg/asset';
type ModuleButtonProps = Omit<ComponentProps<typeof Button>, 'type'> & {
selected?: boolean;
first?: boolean;
last?: boolean;
rowChild?: boolean;
discriminator?: string;
} & (
| {
type: 'module';
module: string;
}
| {
type: 'shell';
shell: string;
}
| {
type: 'equipment';
equipment: number;
}
| {
type: 'consumable';
consumable: number;
}
| {
type: 'provision';
provision: number;
}
| {
type: 'camouflage';
}
);
export function ModuleButton({
selected,
style,
first = false,
last = false,
rowChild,
discriminator,
disabled,
...props
}: ModuleButtonProps) {
const imageStyles: CSSProperties = {
width: 32,
height: 32,
position: 'absolute',
opacity: disabled ? 0.5 : 1,
transform: 'scale(0.75)',
};
if (props.type === 'module') {
imageStyles.top = '50%';
imageStyles.left = '50%';
imageStyles.transform = 'translate(calc(-50% + 2px), calc(-50% + 2px))';
} else if (props.type === 'camouflage') {
imageStyles.top = '50%';
imageStyles.left = '50%';
imageStyles.transform = 'translate(calc(-50% + 4px), calc(-50% + 4px))';
}
return (
<Button
disabled={disabled}
radius="medium"
color={selected ? undefined : 'gray'}
variant={selected ? 'surface' : 'soft'}
style={{
padding: 0,
width: 48,
height: 40,
position: 'relative',
borderTopLeftRadius: first ? undefined : 0,
borderTopRightRadius: last ? undefined : 0,
borderBottomLeftRadius: first ? undefined : 0,
borderBottomRightRadius: last ? undefined : 0,
margin: rowChild ? -0.5 : 'unset',
...style,
}}
{...(props as unknown as ComponentProps<typeof Button>)}
>
<img
draggable={false}
src={asset(
props.type === 'module'
? `icons/modules/${props.module}.webp`
: props.type === 'shell'
? `icons/shells/${props.shell}.webp`
: props.type === 'consumable'
? `icons/consumables/${props.consumable}.webp`
: props.type === 'camouflage'
? `icons/camo.webp`
: props.type === 'provision'
? `icons/provisions/${props.provision}.webp`
: `icons/equipment/${props.equipment}.webp`,
)}
style={imageStyles}
/>
{discriminator !== undefined && (
<Text
size="1"
style={{
zIndex: 1,
position: 'absolute',
top: '50%',
right: 8,
textAlign: 'right',
}}
>
{discriminator}
</Text>
)}
</Button>
);
}
@@ -0,0 +1,17 @@
import { asset } from '../../core/blitzkrieg/asset';
import { GenericTankComponentButton } from './GenericTankComponentButton';
import { TankComponentButtonProps } from './TankComponentButton';
export function CamouflageButton(props: TankComponentButtonProps) {
return (
<GenericTankComponentButton
icon={asset('icons/camo.webp')}
iconStyles={{
top: '50%',
left: '50%',
transform: 'translate(calc(-50% + 4px), calc(-50% + 4px))',
}}
{...props}
/>
);
}
@@ -0,0 +1,19 @@
import { asset } from '../../core/blitzkrieg/asset';
import { GenericTankComponentButton } from './GenericTankComponentButton';
import { TankComponentButtonProps } from './TankComponentButton';
interface ConsumableButtonProps extends TankComponentButtonProps {
consumable: number;
}
export function ConsumableButton({
consumable,
...props
}: ConsumableButtonProps) {
return (
<GenericTankComponentButton
icon={asset(`icons/consumables/${consumable}.webp`)}
{...props}
/>
);
}
@@ -0,0 +1,16 @@
import { asset } from '../../core/blitzkrieg/asset';
import { GenericTankComponentButton } from './GenericTankComponentButton';
import { TankComponentButtonProps } from './TankComponentButton';
interface EquipmentButtonProps extends TankComponentButtonProps {
equipment: number;
}
export function EquipmentButton({ equipment, ...props }: EquipmentButtonProps) {
return (
<GenericTankComponentButton
icon={asset(`icons/equipment/${equipment}.webp`)}
{...props}
/>
);
}
@@ -0,0 +1,33 @@
import { HTMLAttributes } from 'react';
import {
TankComponentButton,
TankComponentButtonProps,
} from './TankComponentButton';
interface GenericTankComponentButtonProps extends TankComponentButtonProps {
icon: string;
iconStyles?: HTMLAttributes<HTMLImageElement>['style'];
}
export function GenericTankComponentButton({
icon,
iconStyles,
...props
}: GenericTankComponentButtonProps) {
return (
<TankComponentButton disabled={props.disabled} {...props}>
<img
draggable={false}
src={icon}
style={{
width: 32,
height: 32,
position: 'absolute',
opacity: props.disabled ? 0.5 : 1,
transform: 'scale(0.75)',
...iconStyles,
}}
/>
</TankComponentButton>
);
}
@@ -0,0 +1,21 @@
import { asset } from '../../core/blitzkrieg/asset';
import { GenericTankComponentButton } from './GenericTankComponentButton';
import { TankComponentButtonProps } from './TankComponentButton';
interface ModuleProps extends TankComponentButtonProps {
module: string;
}
export function ModuleButton({ module, ...props }: ModuleProps) {
return (
<GenericTankComponentButton
icon={asset(`icons/modules/${module}.webp`)}
iconStyles={{
top: '50%',
left: '50%',
transform: 'translate(calc(-50% + 2px), calc(-50% + 2px))',
}}
{...props}
/>
);
}
@@ -0,0 +1,16 @@
import { asset } from '../../core/blitzkrieg/asset';
import { GenericTankComponentButton } from './GenericTankComponentButton';
import { TankComponentButtonProps } from './TankComponentButton';
interface ProvisionButtonProps extends TankComponentButtonProps {
provision: number;
}
export function ProvisionButton({ provision, ...props }: ProvisionButtonProps) {
return (
<GenericTankComponentButton
icon={asset(`icons/provisions/${provision}.webp`)}
{...props}
/>
);
}
@@ -0,0 +1,16 @@
import { asset } from '../../core/blitzkrieg/asset';
import { GenericTankComponentButton } from './GenericTankComponentButton';
import { TankComponentButtonProps } from './TankComponentButton';
interface ShellButtonProps extends TankComponentButtonProps {
shell: string;
}
export function ShellButton({ shell, ...props }: ShellButtonProps) {
return (
<GenericTankComponentButton
icon={asset(`icons/shells/${shell}.webp`)}
{...props}
/>
);
}
@@ -0,0 +1,64 @@
import { Button, Text } from '@radix-ui/themes';
import { ComponentProps, ReactNode } from 'react';
export interface TankComponentButtonProps
extends ComponentProps<typeof Button> {
selected?: boolean;
first?: boolean;
last?: boolean;
rowChild?: boolean;
children?: ReactNode;
discriminator?: ReactNode;
disabled?: boolean;
}
export function TankComponentButton({
selected,
first = false,
last = false,
rowChild,
discriminator,
disabled,
children,
...props
}: TankComponentButtonProps) {
return (
<Button
disabled={disabled}
radius="medium"
color={selected ? undefined : 'gray'}
variant={selected ? 'surface' : 'soft'}
style={{
padding: 0,
width: 48,
height: 40,
position: 'relative',
borderTopLeftRadius: first ? undefined : 0,
borderTopRightRadius: last ? undefined : 0,
borderBottomLeftRadius: first ? undefined : 0,
borderBottomRightRadius: last ? undefined : 0,
margin: rowChild ? -0.5 : 'unset',
}}
{...(props as unknown as ComponentProps<typeof Button>)}
>
{children}
{discriminator !== undefined && (
<Text
size="1"
style={{
color: 'white',
textShadow: '0 0 4px black',
zIndex: 1,
position: 'absolute',
top: '50%',
right: 8,
textAlign: 'right',
}}
>
{discriminator}
</Text>
)}
</Button>
);
}
@@ -36,5 +36,3 @@ export interface ConsumableDefinitions {
export const consumableDefinitions = fetchCdonLz4<ConsumableDefinitions>(
asset('definitions/consumables.cdon.lz4'),
);
consumableDefinitions.then(console.log);