mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 18:57:03 +02:00
feat: code split module buttons
This commit is contained in:
1 parent
9d7c60e92d
commit
574b1eec92
17 files changed
+230
-153
No files matched your search
@@ -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>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user