mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 20:19:49 +02:00
refine layout
This commit is contained in:
1 parent
0a186399b6
commit
d9b22431fa
10 files changed
+45
-128
No files matched your search
@@ -1,19 +1,11 @@
|
|||||||
.characteristics {
|
.characteristics {
|
||||||
padding: var(--space-5);
|
padding: var(--space-5);
|
||||||
padding-top: var(--space-6);
|
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: var(--space-5);
|
gap: var(--space-5);
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
max-height: 100%;
|
|
||||||
overflow-y: auto;
|
|
||||||
|
|
||||||
&[data-visible="false"] {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.group {
|
.group {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
@@ -1,21 +1,17 @@
|
|||||||
import { CaretDownIcon, CaretRightIcon } from "@radix-ui/react-icons";
|
import { CaretDownIcon, CaretRightIcon } from "@radix-ui/react-icons";
|
||||||
|
import { useStrings } from "../../hooks/useStrings";
|
||||||
|
import { Tankopedia } from "../../stores/tankopedia";
|
||||||
import {
|
import {
|
||||||
characteristicsOrder,
|
characteristicsOrder,
|
||||||
type CharacteristicRenderConfig,
|
type CharacteristicRenderConfig,
|
||||||
type CharacteristicsGroup,
|
type CharacteristicsGroup,
|
||||||
} from "../../tankopedia/characteristicsOrder";
|
} from "../../tankopedia/characteristicsOrder";
|
||||||
import styles from "./index.module.css";
|
|
||||||
import { Heading } from "../Heading";
|
import { Heading } from "../Heading";
|
||||||
import { Tankopedia, TankopediaTab } from "../../stores/tankopedia";
|
import styles from "./index.module.css";
|
||||||
import { useStrings } from "../../hooks/useStrings";
|
|
||||||
|
|
||||||
export function TankopediaCharacteristics() {
|
export function TankopediaCharacteristics() {
|
||||||
const isVisible = Tankopedia.use(
|
|
||||||
(state) => state.tab === TankopediaTab.Characteristics,
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.characteristics} data-visible={isVisible}>
|
<div className={styles.characteristics}>
|
||||||
{characteristicsOrder.map((group) => (
|
{characteristicsOrder.map((group) => (
|
||||||
<Group {...group} />
|
<Group {...group} />
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import { romanize } from "@blitzkit/core";
|
import { romanize } from "@blitzkit/core";
|
||||||
|
import type { ConsumableComponent } from "@protos/blitz_static_consumable_component";
|
||||||
import type { BlitzStaticEquipmentPresetComponent_EquipmentSlot } from "@protos/blitz_static_equipment_preset_component";
|
import type { BlitzStaticEquipmentPresetComponent_EquipmentSlot } from "@protos/blitz_static_equipment_preset_component";
|
||||||
|
import type { BlitzStaticPurchaseComponent } from "@protos/blitz_static_purchase_component";
|
||||||
import { Grade } from "@protos/blitz_static_standard_grades_enum";
|
import { Grade } from "@protos/blitz_static_standard_grades_enum";
|
||||||
import { StandardPrice } from "@protos/blitz_static_standard_price";
|
import { StandardPrice } from "@protos/blitz_static_standard_price";
|
||||||
import type { UpgradeLine } from "@protos/blitz_static_tank_upgrade_line";
|
import type { UpgradeLine } from "@protos/blitz_static_tank_upgrade_line";
|
||||||
@@ -24,26 +26,20 @@ import {
|
|||||||
import { useCompatibility } from "../../hooks/useCompatibility";
|
import { useCompatibility } from "../../hooks/useCompatibility";
|
||||||
import { useConsumables } from "../../hooks/useConsumables";
|
import { useConsumables } from "../../hooks/useConsumables";
|
||||||
import { useEquipment } from "../../hooks/useEquipment";
|
import { useEquipment } from "../../hooks/useEquipment";
|
||||||
|
import { useGameStrings } from "../../hooks/useGameStrings";
|
||||||
import { useProtagonist } from "../../hooks/useProtagonist";
|
import { useProtagonist } from "../../hooks/useProtagonist";
|
||||||
import { useStrings } from "../../hooks/useStrings";
|
import { useStrings } from "../../hooks/useStrings";
|
||||||
import { useTierPrices } from "../../hooks/useTierPrices";
|
import { useTierPrices } from "../../hooks/useTierPrices";
|
||||||
import { useUpgradePreset } from "../../hooks/useUpgradePreset";
|
import { useUpgradePreset } from "../../hooks/useUpgradePreset";
|
||||||
import { Tankopedia, TankopediaCompare } from "../../stores/tankopedia";
|
import { Tankopedia } from "../../stores/tankopedia";
|
||||||
|
import type { ComputedCharacteristics } from "../../tankopedia/computeCharacteristics";
|
||||||
import { Button } from "../Button";
|
import { Button } from "../Button";
|
||||||
import { Heading } from "../Heading";
|
import { Heading } from "../Heading";
|
||||||
import { IconButton } from "../IconButton";
|
import { IconButton } from "../IconButton";
|
||||||
import { Price } from "../Price";
|
import { Price } from "../Price";
|
||||||
import { Section } from "../Section";
|
|
||||||
import { Text } from "../Text";
|
import { Text } from "../Text";
|
||||||
import styles from "./index.module.css";
|
|
||||||
import type { ComputedCharacteristics } from "../../tankopedia/computeCharacteristics";
|
|
||||||
import { Tooltip } from "../Tooltip";
|
import { Tooltip } from "../Tooltip";
|
||||||
import { useGameStrings } from "../../hooks/useGameStrings";
|
import styles from "./index.module.css";
|
||||||
import { TankopediaCollapsible } from "../TankopediaCollapsible";
|
|
||||||
import type { ConsumableComponent } from "@protos/blitz_static_consumable_component";
|
|
||||||
import { Tank } from "@protos/tank";
|
|
||||||
import { select } from "three/src/nodes/math/ConditionalNode.js";
|
|
||||||
import type { BlitzStaticPurchaseComponent } from "@protos/blitz_static_purchase_component";
|
|
||||||
|
|
||||||
interface TankopediaLoadoutProps {
|
interface TankopediaLoadoutProps {
|
||||||
characteristics: ComputedCharacteristics;
|
characteristics: ComputedCharacteristics;
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
.tabs {
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
|
|
||||||
.tab {
|
|
||||||
padding: var(--space-3) var(--space-5);
|
|
||||||
border-top: var(--space-2) solid transparent;
|
|
||||||
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&[data-selected="true"] {
|
|
||||||
background: linear-gradient(var(--accent-a4), transparent);
|
|
||||||
border-top: var(--space-2) solid var(--accent-9);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
import { useStrings } from "../../hooks/useStrings";
|
|
||||||
import { Tankopedia, TankopediaTab } from "../../stores/tankopedia";
|
|
||||||
import { Text } from "../Text";
|
|
||||||
import styles from "./index.module.css";
|
|
||||||
|
|
||||||
export function TankopediaNavigation() {
|
|
||||||
const strings = useStrings();
|
|
||||||
const tab = Tankopedia.use((state) => state.tab);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={styles.tabs}>
|
|
||||||
<div
|
|
||||||
className={styles.tab}
|
|
||||||
data-selected={tab === TankopediaTab.Tank}
|
|
||||||
onClick={() => {
|
|
||||||
Tankopedia.mutate((draft) => {
|
|
||||||
draft.tab = TankopediaTab.Tank;
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Text>{strings.tanks.navigation.tank}</Text>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
className={styles.tab}
|
|
||||||
data-selected={tab === TankopediaTab.Characteristics}
|
|
||||||
onClick={() => {
|
|
||||||
Tankopedia.mutate((draft) => {
|
|
||||||
draft.tab = TankopediaTab.Characteristics;
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Text>{strings.tanks.navigation.characteristics}</Text>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
.sandbox {
|
.wrapper {
|
||||||
position: absolute;
|
height: calc(100dvh - 16rem);
|
||||||
top: 0;
|
position: relative;
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
&[data-visible="false"] {
|
.sandbox {
|
||||||
display: none;
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,22 +1,21 @@
|
|||||||
import { Canvas, useLoader } from "@react-three/fiber";
|
|
||||||
import { OrbitControls } from "@react-three/drei";
|
import { OrbitControls } from "@react-three/drei";
|
||||||
import styles from "./index.module.css";
|
import { Canvas, useLoader } from "@react-three/fiber";
|
||||||
import { GLTFLoader } from "three-stdlib";
|
import { GLTFLoader } from "three-stdlib";
|
||||||
import { Tankopedia } from "../../stores/tankopedia";
|
import styles from "./index.module.css";
|
||||||
import { TankopediaTab } from "../../stores/tankopedia";
|
|
||||||
|
|
||||||
export function TankopediaSandbox() {
|
export function TankopediaSandbox() {
|
||||||
const isVisible = Tankopedia.use((state) => state.tab === TankopediaTab.Tank);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.sandbox} data-visible={isVisible}>
|
<div className={styles.wrapper}>
|
||||||
<Canvas
|
<div className={styles.sandbox}>
|
||||||
shadows
|
<Canvas
|
||||||
className={styles.canvas}
|
// scene={{ fog: new Fog("black", 15, 40) }}
|
||||||
frameloop={isVisible ? "always" : "never"}
|
shadows
|
||||||
>
|
className={styles.canvas}
|
||||||
{!import.meta.env.SSR && <Content />}
|
frameloop="demand"
|
||||||
</Canvas>
|
>
|
||||||
|
{!import.meta.env.SSR && <Content />}
|
||||||
|
</Canvas>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -34,8 +33,8 @@ function Content() {
|
|||||||
<pointLight castShadow position={[3, 10, 5]} intensity={1000} />
|
<pointLight castShadow position={[3, 10, 5]} intensity={1000} />
|
||||||
|
|
||||||
<mesh receiveShadow position={[0, -1, 0]} rotation={[-Math.PI / 2, 0, 0]}>
|
<mesh receiveShadow position={[0, -1, 0]} rotation={[-Math.PI / 2, 0, 0]}>
|
||||||
<planeGeometry args={[30, 30]} />
|
<planeGeometry args={[2 ** 8, 2 ** 8]} />
|
||||||
<meshStandardMaterial color="green" />
|
<meshStandardMaterial color="black" />
|
||||||
</mesh>
|
</mesh>
|
||||||
|
|
||||||
<OrbitControls />
|
<OrbitControls />
|
||||||
|
|||||||
@@ -4,13 +4,12 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
.sandbox {
|
.sandbox {
|
||||||
position: relative;
|
|
||||||
|
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
background-color: black;
|
|
||||||
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stats {
|
.loadout {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
@@ -18,5 +17,7 @@
|
|||||||
padding: var(--space-5);
|
padding: var(--space-5);
|
||||||
|
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
|
background-color: var(--gray-2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
import { Fragment, useMemo } from "react";
|
import { Fragment, useMemo } from "react";
|
||||||
import { api } from "../../../../api/dynamic";
|
import { api } from "../../../../api/dynamic";
|
||||||
|
import { TankopediaCharacteristics } from "../../../../components/TankopediaCharacteristics";
|
||||||
import { TankopediaLoadout } from "../../../../components/TankopediaLoadout";
|
import { TankopediaLoadout } from "../../../../components/TankopediaLoadout";
|
||||||
|
import { TankopediaSandbox } from "../../../../components/TankopediaSandbox";
|
||||||
import { withErrorWrapper } from "../../../../hocs/withErrorWrapper";
|
import { withErrorWrapper } from "../../../../hocs/withErrorWrapper";
|
||||||
import { withLocale } from "../../../../hocs/withLocale";
|
import { withLocale } from "../../../../hocs/withLocale";
|
||||||
import { useAwait } from "../../../../hooks/useAwait";
|
import { useAwait } from "../../../../hooks/useAwait";
|
||||||
@@ -10,9 +12,6 @@ import { Tankopedia } from "../../../../stores/tankopedia";
|
|||||||
import { characteristicsOrder } from "../../../../tankopedia/characteristicsOrder";
|
import { characteristicsOrder } from "../../../../tankopedia/characteristicsOrder";
|
||||||
import { computeCharacteristics } from "../../../../tankopedia/computeCharacteristics";
|
import { computeCharacteristics } from "../../../../tankopedia/computeCharacteristics";
|
||||||
import styles from "./_index.module.css";
|
import styles from "./_index.module.css";
|
||||||
import { TankopediaSandbox } from "../../../../components/TankopediaSandbox";
|
|
||||||
import { TankopediaNavigation } from "../../../../components/TankopediaNavigation";
|
|
||||||
import { TankopediaCharacteristics } from "../../../../components/TankopediaCharacteristics";
|
|
||||||
|
|
||||||
interface PageProps {
|
interface PageProps {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -24,8 +23,6 @@ export const Page = withErrorWrapper(
|
|||||||
|
|
||||||
Tankopedia.useInitialization(protagonistTank);
|
Tankopedia.useInitialization(protagonistTank);
|
||||||
|
|
||||||
// const renderCharacteristic = useCharacteristicRenderer();
|
|
||||||
|
|
||||||
const protagonist = Tankopedia.use((state) => state.protagonist);
|
const protagonist = Tankopedia.use((state) => state.protagonist);
|
||||||
const protagonistEquipment = useEquipment(protagonistTank.tank!);
|
const protagonistEquipment = useEquipment(protagonistTank.tank!);
|
||||||
|
|
||||||
@@ -41,14 +38,13 @@ export const Page = withErrorWrapper(
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.page}>
|
<div className={styles.page}>
|
||||||
|
<div className={styles.loadout}>
|
||||||
|
<TankopediaLoadout characteristics={characteristics} />
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className={styles.sandbox}>
|
<div className={styles.sandbox}>
|
||||||
<TankopediaSandbox />
|
<TankopediaSandbox />
|
||||||
<TankopediaCharacteristics />
|
<TankopediaCharacteristics />
|
||||||
<TankopediaNavigation />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className={styles.stats}>
|
|
||||||
<TankopediaLoadout characteristics={characteristics} />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import { characteristicsOrder } from "../tankopedia/characteristicsOrder";
|
|||||||
|
|
||||||
interface Tankopedia {
|
interface Tankopedia {
|
||||||
compare: TankopediaCompare;
|
compare: TankopediaCompare;
|
||||||
tab: TankopediaTab;
|
|
||||||
groups: Record<string, boolean>;
|
groups: Record<string, boolean>;
|
||||||
|
|
||||||
protagonist: TankState;
|
protagonist: TankState;
|
||||||
@@ -18,11 +17,6 @@ export enum TankopediaCompare {
|
|||||||
All,
|
All,
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum TankopediaTab {
|
|
||||||
Tank,
|
|
||||||
Characteristics,
|
|
||||||
}
|
|
||||||
|
|
||||||
const groups: Record<string, boolean> = {};
|
const groups: Record<string, boolean> = {};
|
||||||
|
|
||||||
for (const { group } of characteristicsOrder) {
|
for (const { group } of characteristicsOrder) {
|
||||||
@@ -31,7 +25,6 @@ for (const { group } of characteristicsOrder) {
|
|||||||
|
|
||||||
export const Tankopedia = new Varuna<Tankopedia, Tank>((tank) => ({
|
export const Tankopedia = new Varuna<Tankopedia, Tank>((tank) => ({
|
||||||
compare: TankopediaCompare.TierAndClass,
|
compare: TankopediaCompare.TierAndClass,
|
||||||
tab: TankopediaTab.Characteristics,
|
|
||||||
groups,
|
groups,
|
||||||
|
|
||||||
protagonist: createTankState(tank),
|
protagonist: createTankState(tank),
|
||||||
|
|||||||
Reference in new issue
Block a user