mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 19:49:50 +02:00
feat: more customizations
This commit is contained in:
1 parent
6a18abf17f
commit
38f3ccfbd8
4 files changed
+627
-333
No files matched your search
@@ -1,13 +1,11 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { Box } from '@radix-ui/themes';
|
|
||||||
import { Dispatch, SetStateAction, use, useState } from 'react';
|
import { Dispatch, SetStateAction, use, useState } from 'react';
|
||||||
import { EmbedConfigInputs } from '../../../../../components/EmbedConfigInputs';
|
import { EmbedConfigInputs } from '../../../../../components/EmbedConfigInputs';
|
||||||
import {
|
import {
|
||||||
TanksEmbedCard,
|
TanksEmbedCard,
|
||||||
TanksEmbedWrapper,
|
TanksEmbedWrapper,
|
||||||
} from '../../../../../components/TanksEmbed';
|
} from '../../../../../components/TanksEmbed';
|
||||||
import { imgur } from '../../../../../core/blitzkit/imgur';
|
|
||||||
import { tanksDefinitionsArray } from '../../../../../core/blitzkit/tankDefinitions';
|
import { tanksDefinitionsArray } from '../../../../../core/blitzkit/tankDefinitions';
|
||||||
import {
|
import {
|
||||||
EmbedConfig,
|
EmbedConfig,
|
||||||
@@ -17,9 +15,11 @@ import {
|
|||||||
import { extractEmbedConfigDefaults } from '../../utilities';
|
import { extractEmbedConfigDefaults } from '../../utilities';
|
||||||
|
|
||||||
const tankEmbedConfig = {
|
const tankEmbedConfig = {
|
||||||
|
showTotal: { type: EmbedConfigType.Boolean, default: true },
|
||||||
|
|
||||||
listWidth: { type: EmbedConfigType.Number, default: 320, unit: 'px' },
|
listWidth: { type: EmbedConfigType.Number, default: 320, unit: 'px' },
|
||||||
listGap: { type: EmbedConfigType.Size, default: '2' },
|
listGap: { type: EmbedConfigType.Size, default: '2' },
|
||||||
listMaxTanks: { type: EmbedConfigType.Number, default: 8, pad: true },
|
listMaxTanks: { type: EmbedConfigType.Number, default: 4, pad: true },
|
||||||
|
|
||||||
cardRadius: { type: EmbedConfigType.Radius, default: '2' },
|
cardRadius: { type: EmbedConfigType.Radius, default: '2' },
|
||||||
cardHeaderBackgroundColor: {
|
cardHeaderBackgroundColor: {
|
||||||
@@ -27,6 +27,12 @@ const tankEmbedConfig = {
|
|||||||
default: { base: 'gray', variant: '3' },
|
default: { base: 'gray', variant: '3' },
|
||||||
},
|
},
|
||||||
cardHeaderPadding: { type: EmbedConfigType.Size, default: '1' },
|
cardHeaderPadding: { type: EmbedConfigType.Size, default: '1' },
|
||||||
|
cardTitle: {
|
||||||
|
type: EmbedConfigType.FullTextControl,
|
||||||
|
default: { color: undefined, weight: 'bold', size: '3' },
|
||||||
|
},
|
||||||
|
cardTitleAutoColor: { type: EmbedConfigType.Boolean, default: true },
|
||||||
|
cardTitleAutoIcon: { type: EmbedConfigType.Boolean, default: true },
|
||||||
cardBodyBackgroundColor: {
|
cardBodyBackgroundColor: {
|
||||||
type: EmbedConfigType.Color,
|
type: EmbedConfigType.Color,
|
||||||
default: { base: 'gray', variant: '2' },
|
default: { base: 'gray', variant: '2' },
|
||||||
@@ -34,12 +40,13 @@ const tankEmbedConfig = {
|
|||||||
cardBodyPadding: { type: EmbedConfigType.Size, default: '2', pad: true },
|
cardBodyPadding: { type: EmbedConfigType.Size, default: '2', pad: true },
|
||||||
|
|
||||||
columnGap: { type: EmbedConfigType.Size, default: '0' },
|
columnGap: { type: EmbedConfigType.Size, default: '0' },
|
||||||
columnValueSize: { type: EmbedConfigType.SizeNo0, default: '3' },
|
columnValue: {
|
||||||
columnValueColor: { type: EmbedConfigType.TextColor, default: undefined },
|
type: EmbedConfigType.FullTextControl,
|
||||||
columnLabelSize: { type: EmbedConfigType.SizeNo0, default: '2' },
|
default: { color: undefined, size: '3', weight: 'regular' },
|
||||||
columnLabelColor: {
|
},
|
||||||
type: EmbedConfigType.TextColor,
|
columnLabel: {
|
||||||
default: 'gray',
|
type: EmbedConfigType.FullTextControl,
|
||||||
|
default: { color: 'gray', size: '2', weight: 'regular' },
|
||||||
pad: true,
|
pad: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -62,29 +69,22 @@ export default function Page() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<EmbedConfigInputs
|
||||||
width="100vw"
|
config={tankEmbedConfig}
|
||||||
height="100vh"
|
state={state}
|
||||||
style={{
|
setState={
|
||||||
background: `url(${imgur('pAidayf')})`,
|
setState as Dispatch<
|
||||||
backgroundSize: 'cover',
|
SetStateAction<ExtractEmbedConfigType<EmbedConfig>>
|
||||||
}}
|
>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<TanksEmbedWrapper state={state}>
|
<TanksEmbedWrapper state={state}>
|
||||||
|
{state.showTotal && <TanksEmbedCard state={state} tank={null} />}
|
||||||
|
|
||||||
{tanks.slice(0, state.listMaxTanks).map((tank) => (
|
{tanks.slice(0, state.listMaxTanks).map((tank) => (
|
||||||
<TanksEmbedCard key={tank.id} tank={tank} state={state} />
|
<TanksEmbedCard key={tank.id} tank={tank} state={state} />
|
||||||
))}
|
))}
|
||||||
</TanksEmbedWrapper>
|
</TanksEmbedWrapper>
|
||||||
|
</EmbedConfigInputs>
|
||||||
<EmbedConfigInputs
|
|
||||||
config={tankEmbedConfig}
|
|
||||||
state={state}
|
|
||||||
setState={
|
|
||||||
setState as Dispatch<
|
|
||||||
SetStateAction<ExtractEmbedConfigType<EmbedConfig>>
|
|
||||||
>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -8,6 +8,8 @@ export enum EmbedConfigType {
|
|||||||
SizeNo0,
|
SizeNo0,
|
||||||
TextColor,
|
TextColor,
|
||||||
String,
|
String,
|
||||||
|
FullTextControl,
|
||||||
|
Boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const radixGrays = [
|
export const radixGrays = [
|
||||||
@@ -19,9 +21,15 @@ export const radixGrays = [
|
|||||||
'sand',
|
'sand',
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
|
export const radixTextWeights = ['light', 'regular', 'medium', 'bold'] as const;
|
||||||
|
|
||||||
export type EmbedConfig = Record<string, EmbedConfigItem>;
|
export type EmbedConfig = Record<string, EmbedConfigItem>;
|
||||||
|
|
||||||
export type EmbedConfigItem = (
|
export type EmbedConfigItem = (
|
||||||
|
| {
|
||||||
|
type: EmbedConfigType.Boolean;
|
||||||
|
default: boolean;
|
||||||
|
}
|
||||||
| {
|
| {
|
||||||
type: EmbedConfigType.Number;
|
type: EmbedConfigType.Number;
|
||||||
default: number;
|
default: number;
|
||||||
@@ -51,12 +59,24 @@ export type EmbedConfigItem = (
|
|||||||
type: EmbedConfigType.TextColor;
|
type: EmbedConfigType.TextColor;
|
||||||
default: RadixTextColor;
|
default: RadixTextColor;
|
||||||
}
|
}
|
||||||
|
| {
|
||||||
|
type: EmbedConfigType.FullTextControl;
|
||||||
|
default: {
|
||||||
|
color: RadixTextColor;
|
||||||
|
size: RadixSizeNo0;
|
||||||
|
weight: RadixTextWeight;
|
||||||
|
};
|
||||||
|
}
|
||||||
) & {
|
) & {
|
||||||
pad?: boolean;
|
pad?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type EmbedConfigItemType<Type extends EmbedConfigType> =
|
||||||
|
(EmbedConfigItem & { type: Type })['default'];
|
||||||
|
|
||||||
export type RadixRadius = `${1 | 2 | 3 | 4}` | 'full';
|
export type RadixRadius = `${1 | 2 | 3 | 4}` | 'full';
|
||||||
export type RadixSize = `${0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9}`;
|
export type RadixSize = `${0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9}`;
|
||||||
|
export type RadixTextWeight = (typeof radixTextWeights)[number];
|
||||||
export type RadixSizeNo0 = Exclude<RadixSize, '0'>;
|
export type RadixSizeNo0 = Exclude<RadixSize, '0'>;
|
||||||
export type RadixColor = { base: RadixColorBase; variant: RadixColorVariant };
|
export type RadixColor = { base: RadixColorBase; variant: RadixColorVariant };
|
||||||
export type RadixColorBase = Exclude<
|
export type RadixColorBase = Exclude<
|
||||||
|
|||||||
@@ -1,25 +1,37 @@
|
|||||||
import * as radixColors from '@radix-ui/colors';
|
import * as radixColors from '@radix-ui/colors';
|
||||||
import { DragHandleDots2Icon } from '@radix-ui/react-icons';
|
import {
|
||||||
|
DragHandleDots2Icon,
|
||||||
|
EnterFullScreenIcon,
|
||||||
|
ExitFullScreenIcon,
|
||||||
|
ImageIcon,
|
||||||
|
} from '@radix-ui/react-icons';
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
|
Button,
|
||||||
Card,
|
Card,
|
||||||
Flex,
|
Flex,
|
||||||
|
IconButton,
|
||||||
|
Inset,
|
||||||
ScrollArea,
|
ScrollArea,
|
||||||
Select,
|
Select,
|
||||||
|
Switch,
|
||||||
Text,
|
Text,
|
||||||
TextField,
|
TextField,
|
||||||
} from '@radix-ui/themes';
|
} from '@radix-ui/themes';
|
||||||
import { produce } from 'immer';
|
import { produce } from 'immer';
|
||||||
import { capitalize, startCase, times } from 'lodash';
|
import { capitalize, clamp, startCase, times } from 'lodash';
|
||||||
import {
|
import {
|
||||||
Dispatch,
|
Dispatch,
|
||||||
ReactNode,
|
ReactNode,
|
||||||
SetStateAction,
|
SetStateAction,
|
||||||
useCallback,
|
useCallback,
|
||||||
|
useEffect,
|
||||||
useRef,
|
useRef,
|
||||||
|
useState,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import {
|
import {
|
||||||
EmbedConfig,
|
EmbedConfig,
|
||||||
|
EmbedConfigItemType,
|
||||||
EmbedConfigType,
|
EmbedConfigType,
|
||||||
ExtractEmbedConfigType,
|
ExtractEmbedConfigType,
|
||||||
RadixColor,
|
RadixColor,
|
||||||
@@ -29,7 +41,10 @@ import {
|
|||||||
radixGrays,
|
radixGrays,
|
||||||
RadixRadius,
|
RadixRadius,
|
||||||
RadixSize,
|
RadixSize,
|
||||||
|
RadixSizeNo0,
|
||||||
RadixTextColor,
|
RadixTextColor,
|
||||||
|
RadixTextWeight,
|
||||||
|
radixTextWeights,
|
||||||
} from '../app/tools/embed/types';
|
} from '../app/tools/embed/types';
|
||||||
import { toColorVar, toRadiusVar } from '../app/tools/embed/utilities';
|
import { toColorVar, toRadiusVar } from '../app/tools/embed/utilities';
|
||||||
|
|
||||||
@@ -37,13 +52,19 @@ interface EmbedConfigInputsProps {
|
|||||||
config: EmbedConfig;
|
config: EmbedConfig;
|
||||||
state: ExtractEmbedConfigType<EmbedConfig>;
|
state: ExtractEmbedConfigType<EmbedConfig>;
|
||||||
setState: Dispatch<SetStateAction<ExtractEmbedConfigType<EmbedConfig>>>;
|
setState: Dispatch<SetStateAction<ExtractEmbedConfigType<EmbedConfig>>>;
|
||||||
|
children: ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function EmbedConfigInputs({
|
export function EmbedConfigInputs({
|
||||||
config,
|
config,
|
||||||
state,
|
state,
|
||||||
setState,
|
setState,
|
||||||
|
children,
|
||||||
}: EmbedConfigInputsProps) {
|
}: EmbedConfigInputsProps) {
|
||||||
|
const [expanded, setExpanded] = useState(true);
|
||||||
|
const [backgroundImage, setBackgroundImage] = useState(
|
||||||
|
'https://upload.wikimedia.org/wikipedia/commons/f/f6/Swiss_National_Park_131.JPG',
|
||||||
|
);
|
||||||
const mutateState = useCallback(
|
const mutateState = useCallback(
|
||||||
(recipe: (draft: ExtractEmbedConfigType<EmbedConfig>) => void) => {
|
(recipe: (draft: ExtractEmbedConfigType<EmbedConfig>) => void) => {
|
||||||
setState(produce(recipe));
|
setState(produce(recipe));
|
||||||
@@ -56,164 +77,133 @@ export function EmbedConfigInputs({
|
|||||||
|
|
||||||
if (!wrapper.current) return;
|
if (!wrapper.current) return;
|
||||||
|
|
||||||
wrapper.current.style.top = `${parseFloat(wrapper.current.style.top) + event.movementY}px`;
|
wrapper.current.style.top = `${clamp(parseFloat(wrapper.current.style.top) + event.movementY, 32, window.innerHeight - 32 - 32)}px`;
|
||||||
wrapper.current.style.right = `${parseFloat(wrapper.current.style.right) - event.movementX}px`;
|
wrapper.current.style.right = `${clamp(parseFloat(wrapper.current.style.right) - event.movementX, 32, window.innerWidth - 32 - 320)}px`;
|
||||||
}, []);
|
}, []);
|
||||||
|
const handlePointerUp = useCallback(() => {
|
||||||
const handlePointerUp = useCallback((event: PointerEvent) => {
|
|
||||||
window.removeEventListener('pointermove', handlePointerMove);
|
window.removeEventListener('pointermove', handlePointerMove);
|
||||||
window.removeEventListener('pointerup', handlePointerUp);
|
window.removeEventListener('pointerup', handlePointerUp);
|
||||||
}, []);
|
}, []);
|
||||||
|
const fileInput = useRef<HTMLInputElement>();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fileInput.current = document.createElement('input');
|
||||||
|
fileInput.current.type = 'file';
|
||||||
|
fileInput.current.style.display = 'none';
|
||||||
|
fileInput.current.accept = 'image/*';
|
||||||
|
fileInput.current.onchange = (event) => {
|
||||||
|
const file = (event.target as HTMLInputElement).files?.[0];
|
||||||
|
if (!file) return;
|
||||||
|
setBackgroundImage(URL.createObjectURL(file));
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Flex
|
||||||
style={{ position: 'fixed', top: 0, right: 0, minWidth: 320 }}
|
width="100vw"
|
||||||
ref={wrapper}
|
height="100vh"
|
||||||
|
align="center"
|
||||||
|
justify="center"
|
||||||
|
overflow="hidden"
|
||||||
|
style={{
|
||||||
|
background: `url(${backgroundImage}) center / cover no-repeat`,
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Flex
|
<Card
|
||||||
align="center"
|
style={{ position: 'fixed', top: 32, right: 32, minWidth: 320 }}
|
||||||
justify="center"
|
ref={wrapper}
|
||||||
p="2"
|
|
||||||
mb="2"
|
|
||||||
style={{
|
|
||||||
backgroundColor: 'var(--color-panel-translucent)',
|
|
||||||
borderRadius: 'var(--radius-2)',
|
|
||||||
cursor: 'grab',
|
|
||||||
}}
|
|
||||||
onPointerDown={(event) => {
|
|
||||||
window.addEventListener('pointermove', handlePointerMove);
|
|
||||||
window.addEventListener('pointerup', handlePointerUp);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<DragHandleDots2Icon style={{ transform: 'rotate(90deg)' }} />
|
<Inset mb="4">
|
||||||
</Flex>
|
<Flex
|
||||||
|
align="center"
|
||||||
|
justify="center"
|
||||||
|
p="2"
|
||||||
|
mb={expanded ? '2' : '0'}
|
||||||
|
position="relative"
|
||||||
|
style={{
|
||||||
|
backgroundColor: 'var(--color-panel-translucent)',
|
||||||
|
cursor: 'grab',
|
||||||
|
}}
|
||||||
|
onPointerDown={(event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
window.addEventListener('pointermove', handlePointerMove);
|
||||||
|
window.addEventListener('pointerup', handlePointerUp);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text color="gray" trim="end">
|
||||||
|
<DragHandleDots2Icon style={{ transform: 'rotate(90deg)' }} />
|
||||||
|
</Text>
|
||||||
|
|
||||||
<ScrollArea
|
<Box
|
||||||
scrollbars="vertical"
|
position="absolute"
|
||||||
style={{ height: '100%', maxHeight: 640 }}
|
right="0"
|
||||||
>
|
top="50%"
|
||||||
<Flex direction="column" gap="2">
|
pr="2"
|
||||||
{Object.entries(config).map(([key, setting]) => {
|
style={{ transform: 'translateY(-25%)' }}
|
||||||
let control: ReactNode;
|
>
|
||||||
|
<IconButton
|
||||||
|
variant="ghost"
|
||||||
|
color="gray"
|
||||||
|
onClick={() => setExpanded((expanded) => !expanded)}
|
||||||
|
>
|
||||||
|
{expanded ? <ExitFullScreenIcon /> : <EnterFullScreenIcon />}
|
||||||
|
</IconButton>
|
||||||
|
</Box>
|
||||||
|
</Flex>
|
||||||
|
</Inset>
|
||||||
|
|
||||||
switch (setting.type) {
|
{expanded && (
|
||||||
case EmbedConfigType.Number: {
|
<ScrollArea
|
||||||
control = (
|
scrollbars="vertical"
|
||||||
<TextField.Root
|
style={{ height: '100%', maxHeight: 640 }}
|
||||||
size="1"
|
>
|
||||||
style={{ width: 64 }}
|
<Flex direction="column" gap="2">
|
||||||
type="number"
|
<Button
|
||||||
value={state[key] as number}
|
variant="outline"
|
||||||
onChange={(event) => {
|
color="gray"
|
||||||
mutateState((draft) => {
|
mb="6"
|
||||||
draft[key] = (
|
onClick={() => fileInput.current?.click()}
|
||||||
event.target as HTMLInputElement
|
>
|
||||||
).valueAsNumber;
|
<ImageIcon /> Upload test background
|
||||||
});
|
</Button>
|
||||||
}}
|
|
||||||
>
|
|
||||||
{setting.unit && (
|
|
||||||
<TextField.Slot side="right">px</TextField.Slot>
|
|
||||||
)}
|
|
||||||
</TextField.Root>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case EmbedConfigType.String: {
|
{Object.entries(config).map(([key, setting]) => {
|
||||||
control = (
|
let control: ReactNode;
|
||||||
<TextField.Root
|
|
||||||
placeholder="Empty"
|
|
||||||
size="1"
|
|
||||||
style={{ width: 64 }}
|
|
||||||
value={state[key] as string}
|
|
||||||
onChange={(event) => {
|
|
||||||
mutateState((draft) => {
|
|
||||||
draft[key] = (event.target as HTMLInputElement).value;
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case EmbedConfigType.SizeNo0:
|
switch (setting.type) {
|
||||||
case EmbedConfigType.Size: {
|
case EmbedConfigType.Boolean: {
|
||||||
control = (
|
control = (
|
||||||
<Select.Root
|
<Switch
|
||||||
size="1"
|
checked={state[key] as boolean}
|
||||||
value={state[key] as RadixSize}
|
onCheckedChange={(checked) =>
|
||||||
onValueChange={(value) => {
|
mutateState((draft) => {
|
||||||
mutateState((draft) => {
|
draft[key] = checked;
|
||||||
draft[key] = value as RadixSize;
|
})
|
||||||
});
|
}
|
||||||
}}
|
/>
|
||||||
>
|
);
|
||||||
<Select.Trigger />
|
break;
|
||||||
<Select.Content>
|
}
|
||||||
{times(10, (index) =>
|
|
||||||
setting.type === EmbedConfigType.SizeNo0 &&
|
|
||||||
index === 0 ? null : (
|
|
||||||
<Select.Item key={index} value={`${index}`}>
|
|
||||||
{index}
|
|
||||||
</Select.Item>
|
|
||||||
),
|
|
||||||
)}
|
|
||||||
</Select.Content>
|
|
||||||
</Select.Root>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case EmbedConfigType.Radius: {
|
case EmbedConfigType.FullTextControl: {
|
||||||
control = (
|
control = (
|
||||||
<Select.Root
|
<>
|
||||||
size="1"
|
<Select.Root
|
||||||
value={state[key] as RadixRadius}
|
size="1"
|
||||||
onValueChange={(value) => {
|
value={`${(state[key] as EmbedConfigItemType<EmbedConfigType.FullTextControl>).color}`}
|
||||||
mutateState((draft) => {
|
onValueChange={(value) => {
|
||||||
draft[key] = value as RadixRadius;
|
mutateState((draft) => {
|
||||||
});
|
(
|
||||||
}}
|
draft[
|
||||||
>
|
key
|
||||||
<Select.Trigger />
|
] as EmbedConfigItemType<EmbedConfigType.FullTextControl>
|
||||||
<Select.Content>
|
).color = value as RadixTextColor;
|
||||||
{times(5, (index) => (
|
});
|
||||||
<Select.Item key={index} value={`${index}`}>
|
}}
|
||||||
{index}
|
>
|
||||||
</Select.Item>
|
<Select.Trigger />
|
||||||
))}
|
<Select.Content>
|
||||||
<Select.Item value="full">Full</Select.Item>
|
<Select.Item value="undefined">
|
||||||
</Select.Content>
|
|
||||||
</Select.Root>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case EmbedConfigType.Color: {
|
|
||||||
control = (
|
|
||||||
<>
|
|
||||||
<Select.Root
|
|
||||||
size="1"
|
|
||||||
value={(state[key] as RadixColor).base}
|
|
||||||
onValueChange={(value) => {
|
|
||||||
mutateState((draft) => {
|
|
||||||
(draft[key] as RadixColor).base =
|
|
||||||
value as RadixColorBase;
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Select.Trigger />
|
|
||||||
<Select.Content>
|
|
||||||
{Object.entries(radixColors)
|
|
||||||
.filter(
|
|
||||||
([key]) =>
|
|
||||||
!key.endsWith('A') &&
|
|
||||||
!key.endsWith('P3') &&
|
|
||||||
!key.endsWith('Dark'),
|
|
||||||
)
|
|
||||||
.map(([key]) => (
|
|
||||||
<Select.Item key={key} value={key}>
|
|
||||||
<Box
|
<Box
|
||||||
style={{
|
style={{
|
||||||
display: 'inline-block',
|
display: 'inline-block',
|
||||||
@@ -221,139 +211,338 @@ export function EmbedConfigInputs({
|
|||||||
height: '1em',
|
height: '1em',
|
||||||
verticalAlign: 'text-top',
|
verticalAlign: 'text-top',
|
||||||
borderRadius: toRadiusVar('full'),
|
borderRadius: toRadiusVar('full'),
|
||||||
backgroundColor: toColorVar({
|
backgroundColor: 'white',
|
||||||
base: key as RadixColorBase,
|
|
||||||
variant: '9',
|
|
||||||
}),
|
|
||||||
}}
|
}}
|
||||||
/>{' '}
|
/>{' '}
|
||||||
{capitalize(key)}
|
White
|
||||||
</Select.Item>
|
</Select.Item>
|
||||||
))}
|
<Select.Item value="gray">
|
||||||
</Select.Content>
|
<Box
|
||||||
</Select.Root>
|
style={{
|
||||||
|
display: 'inline-block',
|
||||||
<Select.Root
|
width: '1em',
|
||||||
size="1"
|
height: '1em',
|
||||||
value={(state[key] as RadixColor).variant}
|
verticalAlign: 'text-top',
|
||||||
onValueChange={(value) => {
|
borderRadius: toRadiusVar('full'),
|
||||||
mutateState((draft) => {
|
backgroundColor: 'gray',
|
||||||
(draft[key] as RadixColor).variant =
|
}}
|
||||||
value as RadixColorVariant;
|
/>{' '}
|
||||||
});
|
Gray
|
||||||
}}
|
</Select.Item>
|
||||||
>
|
{Object.entries(radixColors)
|
||||||
<Select.Trigger />
|
.filter(
|
||||||
<Select.Content>
|
([key]) =>
|
||||||
{times(12, (index) => {
|
!key.endsWith('A') &&
|
||||||
const variant =
|
!key.endsWith('P3') &&
|
||||||
`${index + 1}` as RadixColorVariantRaw;
|
!key.endsWith('Dark') &&
|
||||||
|
!radixGrays.includes(key),
|
||||||
return (
|
)
|
||||||
<>
|
.map(([key]) => (
|
||||||
<Select.Item key={key} value={variant}>
|
<Select.Item key={key} value={key}>
|
||||||
<Box
|
|
||||||
style={{
|
|
||||||
display: 'inline-block',
|
|
||||||
width: '1em',
|
|
||||||
height: '1em',
|
|
||||||
verticalAlign: 'text-top',
|
|
||||||
borderRadius: toRadiusVar('full'),
|
|
||||||
backgroundColor: toColorVar({
|
|
||||||
base: (state[key] as RadixColor).base,
|
|
||||||
variant,
|
|
||||||
}),
|
|
||||||
}}
|
|
||||||
/>{' '}
|
|
||||||
{variant}
|
|
||||||
</Select.Item>
|
|
||||||
<Select.Item key={key} value={`a${variant}`}>
|
|
||||||
<Box
|
|
||||||
style={{
|
|
||||||
display: 'inline-block',
|
|
||||||
overflow: 'hidden',
|
|
||||||
width: '1em',
|
|
||||||
height: '1em',
|
|
||||||
verticalAlign: 'text-top',
|
|
||||||
borderRadius: toRadiusVar('full'),
|
|
||||||
backgroundColor: toColorVar({
|
|
||||||
base: (state[key] as RadixColor).base,
|
|
||||||
variant: `a${variant}`,
|
|
||||||
}),
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Box
|
<Box
|
||||||
style={{
|
style={{
|
||||||
width: '50%',
|
display: 'inline-block',
|
||||||
height: '100%',
|
width: '1em',
|
||||||
|
height: '1em',
|
||||||
|
verticalAlign: 'text-top',
|
||||||
|
borderRadius: toRadiusVar('full'),
|
||||||
backgroundColor: toColorVar({
|
backgroundColor: toColorVar({
|
||||||
base: (state[key] as RadixColor).base,
|
base: key as RadixColorBase,
|
||||||
variant,
|
variant: '9',
|
||||||
}),
|
}),
|
||||||
}}
|
}}
|
||||||
/>
|
/>{' '}
|
||||||
</Box>{' '}
|
{capitalize(key)}
|
||||||
{variant} translucent
|
</Select.Item>
|
||||||
|
))}
|
||||||
|
</Select.Content>
|
||||||
|
</Select.Root>
|
||||||
|
<Select.Root
|
||||||
|
size="1"
|
||||||
|
value={
|
||||||
|
(
|
||||||
|
state[
|
||||||
|
key
|
||||||
|
] as EmbedConfigItemType<EmbedConfigType.FullTextControl>
|
||||||
|
).size
|
||||||
|
}
|
||||||
|
onValueChange={(value) => {
|
||||||
|
mutateState((draft) => {
|
||||||
|
(
|
||||||
|
draft[
|
||||||
|
key
|
||||||
|
] as EmbedConfigItemType<EmbedConfigType.FullTextControl>
|
||||||
|
).size = value as RadixSizeNo0;
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Select.Trigger />
|
||||||
|
<Select.Content>
|
||||||
|
{times(9, (index) => (
|
||||||
|
<Select.Item key={index} value={`${index + 1}`}>
|
||||||
|
Size {index + 1}
|
||||||
</Select.Item>
|
</Select.Item>
|
||||||
</>
|
))}
|
||||||
);
|
</Select.Content>
|
||||||
})}
|
</Select.Root>
|
||||||
</Select.Content>
|
<Select.Root
|
||||||
</Select.Root>
|
size="1"
|
||||||
</>
|
value={
|
||||||
);
|
(
|
||||||
break;
|
state[
|
||||||
}
|
key
|
||||||
|
] as EmbedConfigItemType<EmbedConfigType.FullTextControl>
|
||||||
|
).weight
|
||||||
|
}
|
||||||
|
onValueChange={(value) => {
|
||||||
|
mutateState((draft) => {
|
||||||
|
(
|
||||||
|
draft[
|
||||||
|
key
|
||||||
|
] as EmbedConfigItemType<EmbedConfigType.FullTextControl>
|
||||||
|
).weight = value as RadixTextWeight;
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Select.Trigger />
|
||||||
|
<Select.Content>
|
||||||
|
{radixTextWeights.map((weight) => (
|
||||||
|
<Select.Item key={weight} value={weight}>
|
||||||
|
{startCase(weight)}
|
||||||
|
</Select.Item>
|
||||||
|
))}
|
||||||
|
</Select.Content>
|
||||||
|
</Select.Root>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case EmbedConfigType.TextColor: {
|
case EmbedConfigType.Number: {
|
||||||
control = (
|
control = (
|
||||||
<Select.Root
|
<TextField.Root
|
||||||
size="1"
|
size="1"
|
||||||
value={`${state[key]}`}
|
style={{ width: 64 }}
|
||||||
onValueChange={(value) => {
|
type="number"
|
||||||
mutateState((draft) => {
|
value={state[key] as number}
|
||||||
draft[key] = value as RadixTextColor;
|
onChange={(event) => {
|
||||||
});
|
mutateState((draft) => {
|
||||||
}}
|
draft[key] = (
|
||||||
>
|
event.target as HTMLInputElement
|
||||||
<Select.Trigger />
|
).valueAsNumber;
|
||||||
<Select.Content>
|
});
|
||||||
<Select.Item value="undefined">
|
}}
|
||||||
<Box
|
>
|
||||||
style={{
|
{setting.unit && (
|
||||||
display: 'inline-block',
|
<TextField.Slot side="right">px</TextField.Slot>
|
||||||
width: '1em',
|
)}
|
||||||
height: '1em',
|
</TextField.Root>
|
||||||
verticalAlign: 'text-top',
|
);
|
||||||
borderRadius: toRadiusVar('full'),
|
break;
|
||||||
backgroundColor: 'white',
|
}
|
||||||
|
|
||||||
|
case EmbedConfigType.String: {
|
||||||
|
control = (
|
||||||
|
<TextField.Root
|
||||||
|
placeholder="Empty"
|
||||||
|
size="1"
|
||||||
|
style={{ width: 64 }}
|
||||||
|
value={state[key] as string}
|
||||||
|
onChange={(event) => {
|
||||||
|
mutateState((draft) => {
|
||||||
|
draft[key] = (
|
||||||
|
event.target as HTMLInputElement
|
||||||
|
).value;
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case EmbedConfigType.SizeNo0:
|
||||||
|
case EmbedConfigType.Size: {
|
||||||
|
control = (
|
||||||
|
<Select.Root
|
||||||
|
size="1"
|
||||||
|
value={state[key] as RadixSize}
|
||||||
|
onValueChange={(value) => {
|
||||||
|
mutateState((draft) => {
|
||||||
|
draft[key] = value as RadixSize;
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Select.Trigger />
|
||||||
|
<Select.Content>
|
||||||
|
{times(10, (index) =>
|
||||||
|
setting.type === EmbedConfigType.SizeNo0 &&
|
||||||
|
index === 0 ? null : (
|
||||||
|
<Select.Item key={index} value={`${index}`}>
|
||||||
|
{index}
|
||||||
|
</Select.Item>
|
||||||
|
),
|
||||||
|
)}
|
||||||
|
</Select.Content>
|
||||||
|
</Select.Root>
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case EmbedConfigType.Radius: {
|
||||||
|
control = (
|
||||||
|
<Select.Root
|
||||||
|
size="1"
|
||||||
|
value={state[key] as RadixRadius}
|
||||||
|
onValueChange={(value) => {
|
||||||
|
mutateState((draft) => {
|
||||||
|
draft[key] = value as RadixRadius;
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Select.Trigger />
|
||||||
|
<Select.Content>
|
||||||
|
{times(5, (index) => (
|
||||||
|
<Select.Item key={index} value={`${index}`}>
|
||||||
|
{index}
|
||||||
|
</Select.Item>
|
||||||
|
))}
|
||||||
|
<Select.Item value="full">Full</Select.Item>
|
||||||
|
</Select.Content>
|
||||||
|
</Select.Root>
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case EmbedConfigType.Color: {
|
||||||
|
control = (
|
||||||
|
<>
|
||||||
|
<Select.Root
|
||||||
|
size="1"
|
||||||
|
value={(state[key] as RadixColor).base}
|
||||||
|
onValueChange={(value) => {
|
||||||
|
mutateState((draft) => {
|
||||||
|
(draft[key] as RadixColor).base =
|
||||||
|
value as RadixColorBase;
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
/>{' '}
|
>
|
||||||
White
|
<Select.Trigger />
|
||||||
</Select.Item>
|
<Select.Content>
|
||||||
<Select.Item value="gray">
|
{Object.entries(radixColors)
|
||||||
<Box
|
.filter(
|
||||||
style={{
|
([key]) =>
|
||||||
display: 'inline-block',
|
!key.endsWith('A') &&
|
||||||
width: '1em',
|
!key.endsWith('P3') &&
|
||||||
height: '1em',
|
!key.endsWith('Dark'),
|
||||||
verticalAlign: 'text-top',
|
)
|
||||||
borderRadius: toRadiusVar('full'),
|
.map(([key]) => (
|
||||||
backgroundColor: 'gray',
|
<Select.Item key={key} value={key}>
|
||||||
|
<Box
|
||||||
|
style={{
|
||||||
|
display: 'inline-block',
|
||||||
|
width: '1em',
|
||||||
|
height: '1em',
|
||||||
|
verticalAlign: 'text-top',
|
||||||
|
borderRadius: toRadiusVar('full'),
|
||||||
|
backgroundColor: toColorVar({
|
||||||
|
base: key as RadixColorBase,
|
||||||
|
variant: '9',
|
||||||
|
}),
|
||||||
|
}}
|
||||||
|
/>{' '}
|
||||||
|
{capitalize(key)}
|
||||||
|
</Select.Item>
|
||||||
|
))}
|
||||||
|
</Select.Content>
|
||||||
|
</Select.Root>
|
||||||
|
|
||||||
|
<Select.Root
|
||||||
|
size="1"
|
||||||
|
value={(state[key] as RadixColor).variant}
|
||||||
|
onValueChange={(value) => {
|
||||||
|
mutateState((draft) => {
|
||||||
|
(draft[key] as RadixColor).variant =
|
||||||
|
value as RadixColorVariant;
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
/>{' '}
|
>
|
||||||
Gray
|
<Select.Trigger />
|
||||||
</Select.Item>
|
<Select.Content>
|
||||||
{Object.entries(radixColors)
|
{times(12, (index) => {
|
||||||
.filter(
|
const variant =
|
||||||
([key]) =>
|
`${index + 1}` as RadixColorVariantRaw;
|
||||||
!key.endsWith('A') &&
|
|
||||||
!key.endsWith('P3') &&
|
return (
|
||||||
!key.endsWith('Dark') &&
|
<>
|
||||||
!radixGrays.includes(key),
|
<Select.Item key={key} value={variant}>
|
||||||
)
|
<Box
|
||||||
.map(([key]) => (
|
style={{
|
||||||
<Select.Item key={key} value={key}>
|
display: 'inline-block',
|
||||||
|
width: '1em',
|
||||||
|
height: '1em',
|
||||||
|
verticalAlign: 'text-top',
|
||||||
|
borderRadius: toRadiusVar('full'),
|
||||||
|
backgroundColor: toColorVar({
|
||||||
|
base: (state[key] as RadixColor).base,
|
||||||
|
variant,
|
||||||
|
}),
|
||||||
|
}}
|
||||||
|
/>{' '}
|
||||||
|
{variant}
|
||||||
|
</Select.Item>
|
||||||
|
<Select.Item key={key} value={`a${variant}`}>
|
||||||
|
<Box
|
||||||
|
style={{
|
||||||
|
display: 'inline-block',
|
||||||
|
overflow: 'hidden',
|
||||||
|
width: '1em',
|
||||||
|
height: '1em',
|
||||||
|
verticalAlign: 'text-top',
|
||||||
|
borderRadius: toRadiusVar('full'),
|
||||||
|
backgroundColor: toColorVar({
|
||||||
|
base: (state[key] as RadixColor).base,
|
||||||
|
variant: `a${variant}`,
|
||||||
|
}),
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
style={{
|
||||||
|
width: '50%',
|
||||||
|
height: '100%',
|
||||||
|
backgroundColor: toColorVar({
|
||||||
|
base: (state[key] as RadixColor)
|
||||||
|
.base,
|
||||||
|
variant,
|
||||||
|
}),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>{' '}
|
||||||
|
{variant} translucent
|
||||||
|
</Select.Item>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Select.Content>
|
||||||
|
</Select.Root>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case EmbedConfigType.TextColor: {
|
||||||
|
control = (
|
||||||
|
<Select.Root
|
||||||
|
size="1"
|
||||||
|
value={`${state[key]}`}
|
||||||
|
onValueChange={(value) => {
|
||||||
|
mutateState((draft) => {
|
||||||
|
draft[key] = value as RadixTextColor;
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Select.Trigger />
|
||||||
|
<Select.Content>
|
||||||
|
<Select.Item value="undefined">
|
||||||
<Box
|
<Box
|
||||||
style={{
|
style={{
|
||||||
display: 'inline-block',
|
display: 'inline-block',
|
||||||
@@ -361,43 +550,90 @@ export function EmbedConfigInputs({
|
|||||||
height: '1em',
|
height: '1em',
|
||||||
verticalAlign: 'text-top',
|
verticalAlign: 'text-top',
|
||||||
borderRadius: toRadiusVar('full'),
|
borderRadius: toRadiusVar('full'),
|
||||||
backgroundColor: toColorVar({
|
backgroundColor: 'white',
|
||||||
base: key as RadixColorBase,
|
|
||||||
variant: '9',
|
|
||||||
}),
|
|
||||||
}}
|
}}
|
||||||
/>{' '}
|
/>{' '}
|
||||||
{capitalize(key)}
|
White
|
||||||
</Select.Item>
|
</Select.Item>
|
||||||
))}
|
<Select.Item value="gray">
|
||||||
</Select.Content>
|
<Box
|
||||||
</Select.Root>
|
style={{
|
||||||
);
|
display: 'inline-block',
|
||||||
break;
|
width: '1em',
|
||||||
}
|
height: '1em',
|
||||||
}
|
verticalAlign: 'text-top',
|
||||||
|
borderRadius: toRadiusVar('full'),
|
||||||
|
backgroundColor: 'gray',
|
||||||
|
}}
|
||||||
|
/>{' '}
|
||||||
|
Gray
|
||||||
|
</Select.Item>
|
||||||
|
{Object.entries(radixColors)
|
||||||
|
.filter(
|
||||||
|
([key]) =>
|
||||||
|
!key.endsWith('A') &&
|
||||||
|
!key.endsWith('P3') &&
|
||||||
|
!key.endsWith('Dark') &&
|
||||||
|
!radixGrays.includes(key),
|
||||||
|
)
|
||||||
|
.map(([key]) => (
|
||||||
|
<Select.Item key={key} value={key}>
|
||||||
|
<Box
|
||||||
|
style={{
|
||||||
|
display: 'inline-block',
|
||||||
|
width: '1em',
|
||||||
|
height: '1em',
|
||||||
|
verticalAlign: 'text-top',
|
||||||
|
borderRadius: toRadiusVar('full'),
|
||||||
|
backgroundColor: toColorVar({
|
||||||
|
base: key as RadixColorBase,
|
||||||
|
variant: '9',
|
||||||
|
}),
|
||||||
|
}}
|
||||||
|
/>{' '}
|
||||||
|
{capitalize(key)}
|
||||||
|
</Select.Item>
|
||||||
|
))}
|
||||||
|
</Select.Content>
|
||||||
|
</Select.Root>
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
direction="column"
|
direction="column"
|
||||||
gap="1"
|
gap="1"
|
||||||
mb="1"
|
mb="1"
|
||||||
pb={setting.pad ? '6' : undefined}
|
pb={setting.pad ? '6' : undefined}
|
||||||
>
|
>
|
||||||
<Text color="gray" size="2">
|
<Text color="gray" size="2">
|
||||||
{capitalize(startCase(key))}
|
{capitalize(startCase(key))}
|
||||||
</Text>
|
</Text>
|
||||||
{control && <Flex gap="1">{control}</Flex>}
|
{control && <Flex gap="1">{control}</Flex>}
|
||||||
{!control && (
|
{!control && (
|
||||||
<Text color="red" size="1">
|
<Text color="red" size="1">
|
||||||
Immutable
|
Immutable
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</Flex>
|
</Flex>
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
</Card>
|
)}
|
||||||
|
|
||||||
|
{!expanded && (
|
||||||
|
<Flex justify="center">
|
||||||
|
<Text size="2" color="gray">
|
||||||
|
Expand to configure
|
||||||
|
</Text>
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
{children}
|
||||||
|
</Flex>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -8,6 +8,10 @@ import {
|
|||||||
toWidthVar,
|
toWidthVar,
|
||||||
} from '../app/tools/embed/utilities';
|
} from '../app/tools/embed/utilities';
|
||||||
import { TankDefinition } from '../core/blitzkit/tankDefinitions';
|
import { TankDefinition } from '../core/blitzkit/tankDefinitions';
|
||||||
|
import { ClassHeavy } from './ClassIcon/components/ClassHeavy';
|
||||||
|
import { ClassLight } from './ClassIcon/components/ClassLight';
|
||||||
|
import { ClassMedium } from './ClassIcon/components/ClassMedium';
|
||||||
|
import { ClassTankDestroyer } from './ClassIcon/components/ClassTankDestroyer';
|
||||||
|
|
||||||
interface TanksEmbedWrapperProps {
|
interface TanksEmbedWrapperProps {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
@@ -27,11 +31,12 @@ export function TanksEmbedWrapper({ children, state }: TanksEmbedWrapperProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface TanksEmbedCardProps {
|
interface TanksEmbedCardProps {
|
||||||
tank: TankDefinition;
|
tank: TankDefinition | null;
|
||||||
state: TanksEmbedState;
|
state: TanksEmbedState;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function TanksEmbedCard({ tank, state }: TanksEmbedCardProps) {
|
export function TanksEmbedCard({ tank, state }: TanksEmbedCardProps) {
|
||||||
|
const { color: cardTitleColor, ...restCardTitleProps } = state.cardTitle;
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
direction="column"
|
direction="column"
|
||||||
@@ -48,7 +53,40 @@ export function TanksEmbedCard({ tank, state }: TanksEmbedCardProps) {
|
|||||||
}}
|
}}
|
||||||
p={state.cardHeaderPadding}
|
p={state.cardHeaderPadding}
|
||||||
>
|
>
|
||||||
{tank.name}
|
<Text
|
||||||
|
color={
|
||||||
|
state.cardTitleAutoColor
|
||||||
|
? tank === null
|
||||||
|
? cardTitleColor
|
||||||
|
: tank.treeType === 'collector'
|
||||||
|
? 'blue'
|
||||||
|
: tank.treeType === 'premium'
|
||||||
|
? 'amber'
|
||||||
|
: cardTitleColor
|
||||||
|
: cardTitleColor
|
||||||
|
}
|
||||||
|
{...restCardTitleProps}
|
||||||
|
>
|
||||||
|
<Flex align="center" gap="1">
|
||||||
|
{tank !== null && state.cardTitleAutoIcon && (
|
||||||
|
<>
|
||||||
|
{tank.class === 'lightTank' && (
|
||||||
|
<ClassLight width="1em" height="1em" />
|
||||||
|
)}
|
||||||
|
{tank.class === 'mediumTank' && (
|
||||||
|
<ClassMedium width="1em" height="1em" />
|
||||||
|
)}
|
||||||
|
{tank.class === 'heavyTank' && (
|
||||||
|
<ClassHeavy width="1em" height="1em" />
|
||||||
|
)}
|
||||||
|
{tank.class === 'AT-SPG' && (
|
||||||
|
<ClassTankDestroyer width="1em" height="1em" />
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}{' '}
|
||||||
|
{tank === null ? 'Total' : tank.name}
|
||||||
|
</Flex>
|
||||||
|
</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
<Flex p={state.cardBodyPadding}>
|
<Flex p={state.cardBodyPadding}>
|
||||||
@@ -62,10 +100,10 @@ export function TanksEmbedCard({ tank, state }: TanksEmbedCardProps) {
|
|||||||
gap={state.columnGap}
|
gap={state.columnGap}
|
||||||
flexGrow="1"
|
flexGrow="1"
|
||||||
>
|
>
|
||||||
<Text size={state.columnValueSize} color={state.columnValueColor}>
|
<Text {...state.columnValue}>
|
||||||
70{state[`column${column}Unit`]}
|
70{state[`column${column}Unit`]}
|
||||||
</Text>
|
</Text>
|
||||||
<Text size={state.columnLabelSize} color={state.columnLabelColor}>
|
<Text {...state.columnLabel}>
|
||||||
{state[`column${column}Label`]}
|
{state[`column${column}Label`]}
|
||||||
</Text>
|
</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|||||||
Reference in new issue
Block a user