feat: dropdown modules

This commit is contained in:
TrèsAbhi committed 2024-04-01 19:05:55 -05:00
1 parent cc6de50de6
commit 54e012f736
4 files changed
+189 -89

No files matched your search

+2
View File
@@ -118,6 +118,7 @@ interface VehicleDefinitions {
weight: number; weight: number;
terrainResistance: string; terrainResistance: string;
rotationSpeed: number; rotationSpeed: number;
userString: string;
shotDispersionFactors: { shotDispersionFactors: {
vehicleMovement: number; vehicleMovement: number;
vehicleRotation: number; vehicleRotation: number;
@@ -566,6 +567,7 @@ export async function definitions(production: boolean) {
tankDefinitions[tankId].tracks.push({ tankDefinitions[tankId].tracks.push({
id: trackId, id: trackId,
weight: track.weight, weight: track.weight,
name: strings[track.userString],
traverseSpeed: track.rotationSpeed, traverseSpeed: track.rotationSpeed,
dispersion: { dispersion: {
move: track.shotDispersionFactors.vehicleMovement, move: track.shotDispersionFactors.vehicleMovement,
@@ -1,4 +1,5 @@
import { Button, Flex, Heading } from '@radix-ui/themes'; import { Button, DropdownMenu, Flex, Heading } from '@radix-ui/themes';
import { useState } from 'react';
import { ModuleButton } from '../../../../../../../components/ModuleButtons/ModuleButton'; import { ModuleButton } from '../../../../../../../components/ModuleButtons/ModuleButton';
import { TIER_ROMAN_NUMERALS } from '../../../../../../../core/blitzkrieg/tankDefinitions/constants'; import { TIER_ROMAN_NUMERALS } from '../../../../../../../core/blitzkrieg/tankDefinitions/constants';
import { mutateDuel, useDuel } from '../../../../../../../stores/duel'; import { mutateDuel, useDuel } from '../../../../../../../stores/duel';
@@ -12,6 +13,10 @@ export function Modules() {
protagonist.tank.turrets[0].guns.length > 1 || protagonist.tank.turrets[0].guns.length > 1 ||
protagonist.tank.engines.length > 1 || protagonist.tank.engines.length > 1 ||
protagonist.tank.tracks.length > 1; protagonist.tank.tracks.length > 1;
const [turretMenuOpen, setTurretMenuOpen] = useState(false);
const [gunMenuOpen, setGunMenuOpen] = useState(false);
const [engineMenuOpen, setEngineMenuOpen] = useState(false);
const [trackMenuOpen, setTrackMenuOpen] = useState(false);
return ( return (
<ConfigurationChildWrapper> <ConfigurationChildWrapper>
@@ -59,96 +64,180 @@ export function Modules() {
)} )}
</Flex> </Flex>
<Flex gap="2" wrap="wrap"> <Flex gap="1" wrap="wrap">
<Flex> <ModuleButton
{protagonist.tank.turrets.map((turret, index) => { module="turret"
return ( discriminator={TIER_ROMAN_NUMERALS[protagonist.turret.tier]}
<ModuleButton first
key={turret.id} last
selected={protagonist.turret.id === turret.id} rowChild
module="turret" onClick={() => setTurretMenuOpen(true)}
discriminator={TIER_ROMAN_NUMERALS[turret.tier]} />
first={index === 0}
last={index === protagonist.tank.turrets.length - 1}
rowChild
onClick={() => {
mutateDuel((draft) => {
draft.protagonist!.turret = turret;
draft.protagonist!.gun = turret.guns.at(-1)!;
draft.protagonist!.shell = turret.guns.at(-1)!.shells[0];
});
mutateTankopediaTemporary((draft) => {
draft.shot = undefined;
});
}}
/>
);
})}
</Flex>
<Flex> <DropdownMenu.Root
{protagonist.turret.guns.map((gun, index) => { open={turretMenuOpen}
return ( onOpenChange={setTurretMenuOpen}
<ModuleButton >
key={gun.id} <DropdownMenu.Trigger>
module="gun" <div />
discriminator={TIER_ROMAN_NUMERALS[gun.tier]} </DropdownMenu.Trigger>
selected={protagonist.gun.id === gun.id}
first={index === 0}
last={index === protagonist.turret.guns.length - 1}
rowChild
onClick={() => {
mutateDuel((draft) => {
draft.protagonist!.gun = gun;
draft.protagonist!.shell = gun.shells[0];
});
}}
/>
);
})}
</Flex>
<Flex> <DropdownMenu.Content>
{protagonist.tank.engines.map((engine, index) => { <DropdownMenu.RadioGroup value={`${protagonist.turret.id}`}>
return ( {[...protagonist.tank.turrets].reverse().map((turret) => {
<ModuleButton return (
key={engine.id} <DropdownMenu.RadioItem
module="engine" key={turret.id}
discriminator={TIER_ROMAN_NUMERALS[engine.tier]} value={`${turret.id}`}
selected={protagonist.engine.id === engine.id} onClick={() => {
first={index === 0} mutateDuel((draft) => {
last={index === protagonist.tank.engines.length - 1} draft.protagonist!.turret = turret;
rowChild draft.protagonist!.gun = turret.guns.at(-1)!;
onClick={() => { draft.protagonist!.shell =
mutateDuel((draft) => { turret.guns.at(-1)!.shells[0];
draft.protagonist!.engine = engine; });
}); mutateTankopediaTemporary((draft) => {
}} draft.shot = undefined;
/> });
); setTurretMenuOpen(false);
})} }}
</Flex> >
<ModuleButton
variant="ghost"
module="turret"
discriminator={TIER_ROMAN_NUMERALS[turret.tier]}
/>{' '}
{turret.name}
</DropdownMenu.RadioItem>
);
})}
</DropdownMenu.RadioGroup>
</DropdownMenu.Content>
</DropdownMenu.Root>
<Flex> <ModuleButton
{protagonist.tank.tracks.map((track, index) => { module="gun"
return ( discriminator={TIER_ROMAN_NUMERALS[protagonist.gun.tier]}
<ModuleButton first
key={track.id} last
module="chassis" rowChild
discriminator={TIER_ROMAN_NUMERALS[track.tier]} onClick={() => setGunMenuOpen(true)}
selected={protagonist.track.id === track.id} />
first={index === 0}
last={index === protagonist.tank.tracks.length - 1} <DropdownMenu.Root open={gunMenuOpen} onOpenChange={setGunMenuOpen}>
rowChild <DropdownMenu.Trigger>
onClick={() => { <div />
mutateDuel((draft) => { </DropdownMenu.Trigger>
draft.protagonist!.track = track;
}); <DropdownMenu.Content>
}} <DropdownMenu.RadioGroup value={`${protagonist.gun.id}`}>
/> {[...protagonist.turret.guns].reverse().map((gun) => {
); return (
})} <DropdownMenu.RadioItem
</Flex> key={gun.id}
value={`${gun.id}`}
onClick={() => {
mutateDuel((draft) => {
draft.protagonist!.gun = gun;
draft.protagonist!.shell = gun.shells[0];
});
}}
>
<ModuleButton
variant="ghost"
module="gun"
discriminator={TIER_ROMAN_NUMERALS[gun.tier]}
/>{' '}
{gun.name}
</DropdownMenu.RadioItem>
);
})}
</DropdownMenu.RadioGroup>
</DropdownMenu.Content>
</DropdownMenu.Root>
<ModuleButton
module="engine"
discriminator={TIER_ROMAN_NUMERALS[protagonist.engine.tier]}
first
last
rowChild
onClick={() => setEngineMenuOpen(true)}
/>
<DropdownMenu.Root
open={engineMenuOpen}
onOpenChange={setEngineMenuOpen}
>
<DropdownMenu.Trigger>
<div />
</DropdownMenu.Trigger>
<DropdownMenu.Content>
<DropdownMenu.RadioGroup value={`${protagonist.engine.id}`}>
{[...protagonist.tank.engines].reverse().map((engine) => {
return (
<DropdownMenu.RadioItem
key={engine.id}
value={`${engine.id}`}
onClick={() => {
mutateDuel((draft) => {
draft.protagonist!.engine = engine;
});
}}
>
<ModuleButton
variant="ghost"
module="engine"
discriminator={TIER_ROMAN_NUMERALS[engine.tier]}
/>{' '}
{engine.name}
</DropdownMenu.RadioItem>
);
})}
</DropdownMenu.RadioGroup>
</DropdownMenu.Content>
</DropdownMenu.Root>
<ModuleButton
module="chassis"
discriminator={TIER_ROMAN_NUMERALS[protagonist.track.tier]}
first
last
rowChild
onClick={() => setTrackMenuOpen(true)}
/>
<DropdownMenu.Root open={trackMenuOpen} onOpenChange={setTrackMenuOpen}>
<DropdownMenu.Trigger>
<div />
</DropdownMenu.Trigger>
<DropdownMenu.Content>
<DropdownMenu.RadioGroup value={`${protagonist.track.id}`}>
{[...protagonist.tank.tracks].reverse().map((track) => {
return (
<DropdownMenu.RadioItem
key={track.id}
value={`${track.id}`}
onClick={() => {
mutateDuel((draft) => {
draft.protagonist!.track = track;
});
}}
>
<ModuleButton
variant="ghost"
module="chassis"
discriminator={TIER_ROMAN_NUMERALS[track.tier]}
/>{' '}
{track.name}
</DropdownMenu.RadioItem>
);
})}
</DropdownMenu.RadioGroup>
</DropdownMenu.Content>
</DropdownMenu.Root>
</Flex> </Flex>
</ConfigurationChildWrapper> </ConfigurationChildWrapper>
); );
@@ -15,6 +15,7 @@ export interface TankComponentButtonProps
} }
export function TankComponentButton({ export function TankComponentButton({
variant,
selected, selected,
first = false, first = false,
last = false, last = false,
@@ -23,13 +24,15 @@ export function TankComponentButton({
special, special,
children, children,
banner, banner,
disabled,
style,
...props ...props
}: TankComponentButtonProps) { }: TankComponentButtonProps) {
return ( return (
<Button <Button
radius="medium" radius="medium"
color={selected ? (special ? 'amber' : undefined) : 'gray'} color={selected ? (special ? 'amber' : undefined) : 'gray'}
variant={selected ? 'surface' : 'soft'} variant={variant ?? (selected ? 'surface' : 'soft')}
style={{ style={{
padding: 0, padding: 0,
minWidth: 48, minWidth: 48,
@@ -41,7 +44,11 @@ export function TankComponentButton({
borderBottomRightRadius: last ? undefined : 0, borderBottomRightRadius: last ? undefined : 0,
margin: rowChild ? -0.5 : 'unset', margin: rowChild ? -0.5 : 'unset',
overflow: 'hidden', overflow: 'hidden',
cursor: 'unset',
pointerEvents: variant === 'ghost' ? 'none' : undefined,
...style,
}} }}
disabled={variant === 'ghost' || disabled}
{...props} {...props}
> >
{banner !== undefined && ( {banner !== undefined && (
@@ -69,6 +76,7 @@ export function TankComponentButton({
right: 8, right: 8,
textAlign: 'right', textAlign: 'right',
}} }}
color={variant === 'ghost' ? 'gray' : undefined}
> >
{discriminator} {discriminator}
</Text> </Text>
@@ -55,6 +55,7 @@ export interface TankDefinition {
export interface TrackDefinition { export interface TrackDefinition {
id: number; id: number;
tier: Tier; tier: Tier;
name: string;
weight: number; weight: number;
traverseSpeed: number; traverseSpeed: number;
xp?: number; xp?: number;