Replace Atmoshpere Input with Slider and Add lower bound to gravity
This commit is contained in:
parent
f85faeb6ad
commit
6c39b77949
9 changed files with 123 additions and 33 deletions
|
@ -25,7 +25,7 @@
|
||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bits-ui": "^0.21.8",
|
"bits-ui": "^0.21.9",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"cmdk-sv": "^0.0.17",
|
"cmdk-sv": "^0.0.17",
|
||||||
"svelte-radix": "^1.1.0",
|
"svelte-radix": "^1.1.0",
|
||||||
|
|
26
src/lib/components/Atmosphere.svelte
Normal file
26
src/lib/components/Atmosphere.svelte
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<svelte:options runes />
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import {Label} from "$lib/components/ui/label";
|
||||||
|
import {Slider} from "$lib/components/ui/slider";
|
||||||
|
import {Localization} from "$lib/constants";
|
||||||
|
|
||||||
|
let { i18n = new Localization("en-GB"), value = $bindable() } = $props();
|
||||||
|
let array = $derived([value * 100])
|
||||||
|
|
||||||
|
let valid = $derived(typeof value !== "undefined");
|
||||||
|
|
||||||
|
function handleChange(change: number) {
|
||||||
|
value = change / 100;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if valid}
|
||||||
|
<Label for="atmosDensity">{i18n.localize("atmosDensity")} ({(value * 100).toFixed(0)}%)</Label>
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<Label for="atmosDensity">0%</Label>
|
||||||
|
<Slider id="atmosDensity" value={array} onValueChange={handleChange} min={0} max={100} step={1} />
|
||||||
|
<Label>100%</Label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/if}
|
|
@ -47,6 +47,7 @@
|
||||||
|
|
||||||
{#if valid}
|
{#if valid}
|
||||||
<div class="flex flex-col flex-wrap gap-3 max-w-fit place-self-center items-center">
|
<div class="flex flex-col flex-wrap gap-3 max-w-fit place-self-center items-center">
|
||||||
|
<div>
|
||||||
<DropdownMenu.Root>
|
<DropdownMenu.Root>
|
||||||
<DropdownMenu.Trigger>
|
<DropdownMenu.Trigger>
|
||||||
<Button variant="secondary">{i18n.localize(name)}</Button>
|
<Button variant="secondary">{i18n.localize(name)}</Button>
|
||||||
|
@ -59,7 +60,8 @@
|
||||||
</DropdownMenu.RadioGroup>
|
</DropdownMenu.RadioGroup>
|
||||||
</DropdownMenu.Content>
|
</DropdownMenu.Content>
|
||||||
</DropdownMenu.Root>
|
</DropdownMenu.Root>
|
||||||
<Button class="bg-primary max-w-fit" onclick={() => onAddInventory(construct())}>{i18n.localize("addInventory")}</Button>
|
</div>
|
||||||
|
<Button class="bg-primary max-w-fit" onmousedown={() => onAddInventory(construct())}>{i18n.localize("addInventory")}</Button>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<p>Invalid Props</p>
|
<p>Invalid Props</p>
|
||||||
|
|
|
@ -108,7 +108,7 @@
|
||||||
</DropdownMenu.Content>
|
</DropdownMenu.Content>
|
||||||
</DropdownMenu.Root>
|
</DropdownMenu.Root>
|
||||||
</div>
|
</div>
|
||||||
<Button vclass="bg-primary max-w-fit" onclick={() => onAddThruster(construct())}>{i18n.localize("addThruster")}</Button>
|
<Button vclass="bg-primary max-w-fit" onmousedown={() => onAddThruster(construct())}>{i18n.localize("addThruster")}</Button>
|
||||||
{:else}
|
{:else}
|
||||||
<p>Invalid Props</p>
|
<p>Invalid Props</p>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
26
src/lib/components/WeightOutputSegment.svelte
Normal file
26
src/lib/components/WeightOutputSegment.svelte
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<svelte:options runes />
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import {Localization, weightConversion} from "$lib/constants";
|
||||||
|
|
||||||
|
let { i18n = new Localization("en-GB"), maxWeight, maxVehicleWeight } = $props();
|
||||||
|
|
||||||
|
let valid = $derived.by(() => {
|
||||||
|
let valids = [];
|
||||||
|
valids[0] = typeof maxWeight !== "undefined";
|
||||||
|
valids[1] = typeof maxVehicleWeight !== "undefined";
|
||||||
|
return !valids.includes(false);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if valid}
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<p>{i18n.localize("liftableVehcileWeight")}:</p>
|
||||||
|
{#if maxVehicleWeight < 0}
|
||||||
|
<p class="text-destructive">{weightConversion(i18n, maxVehicleWeight)}</p>
|
||||||
|
{:else}
|
||||||
|
<p>{weightConversion(i18n, maxVehicleWeight)}</p>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<p>{i18n.localize("liftableWeight")}: {weightConversion(i18n, maxWeight)}</p>
|
||||||
|
{/if}
|
7
src/lib/components/ui/slider/index.ts
Normal file
7
src/lib/components/ui/slider/index.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import Root from "./slider.svelte";
|
||||||
|
|
||||||
|
export {
|
||||||
|
Root,
|
||||||
|
//
|
||||||
|
Root as Slider,
|
||||||
|
};
|
27
src/lib/components/ui/slider/slider.svelte
Normal file
27
src/lib/components/ui/slider/slider.svelte
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { Slider as SliderPrimitive } from "bits-ui";
|
||||||
|
import { cn } from "$lib/utils.js";
|
||||||
|
|
||||||
|
type $$Props = SliderPrimitive.Props;
|
||||||
|
|
||||||
|
let className: $$Props["class"] = undefined;
|
||||||
|
export let value: $$Props["value"] = [0];
|
||||||
|
export { className as class };
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<SliderPrimitive.Root
|
||||||
|
bind:value
|
||||||
|
class={cn("relative flex w-full touch-none select-none items-center", className)}
|
||||||
|
{...$$restProps}
|
||||||
|
let:thumbs
|
||||||
|
>
|
||||||
|
<span class="relative h-1.5 w-full grow overflow-hidden rounded-full bg-primary/20">
|
||||||
|
<SliderPrimitive.Range class="absolute h-full bg-primary" />
|
||||||
|
</span>
|
||||||
|
{#each thumbs as thumb}
|
||||||
|
<SliderPrimitive.Thumb
|
||||||
|
{thumb}
|
||||||
|
class="block h-4 w-4 rounded-full border border-primary/50 bg-background shadow transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50"
|
||||||
|
/>
|
||||||
|
{/each}
|
||||||
|
</SliderPrimitive.Root>
|
|
@ -21,6 +21,10 @@
|
||||||
import NewInventory from "$lib/components/NewInventory.svelte";
|
import NewInventory from "$lib/components/NewInventory.svelte";
|
||||||
import {Inventory} from "$lib/containers.svelte";
|
import {Inventory} from "$lib/containers.svelte";
|
||||||
import InventoryList from "$lib/components/InventoryList.svelte";
|
import InventoryList from "$lib/components/InventoryList.svelte";
|
||||||
|
import type {Thruster} from "$lib/thruster.svelte";
|
||||||
|
import {Slider} from "$lib/components/ui/slider";
|
||||||
|
import Atmosphere from "$lib/components/Atmosphere.svelte";
|
||||||
|
import WeightOutputSegment from "$lib/components/WeightOutputSegment.svelte";
|
||||||
|
|
||||||
const STORAGE_VERSION = "2";
|
const STORAGE_VERSION = "2";
|
||||||
let i18n = $state(new Localization("en-GB"));
|
let i18n = $state(new Localization("en-GB"));
|
||||||
|
@ -67,6 +71,7 @@
|
||||||
let maxVehicleWeight: number = $derived(maxWeight - ship.getTotalVolume(inventoryMultiplier) * material.density)
|
let maxVehicleWeight: number = $derived(maxWeight - ship.getTotalVolume(inventoryMultiplier) * material.density)
|
||||||
|
|
||||||
function addInventory(newInventory: Inventory) {
|
function addInventory(newInventory: Inventory) {
|
||||||
|
console.log("triggered")
|
||||||
ship.addInventory(newInventory);
|
ship.addInventory(newInventory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,6 +87,12 @@
|
||||||
ship.removeThruster(index);
|
ship.removeThruster(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleGravityChange() {
|
||||||
|
if (gravity <= 0) {
|
||||||
|
gravity = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
if (navigator) {
|
if (navigator) {
|
||||||
i18n.language = navigator.language;
|
i18n.language = navigator.language;
|
||||||
|
@ -157,24 +168,23 @@
|
||||||
{#if ship.grid === size}
|
{#if ship.grid === size}
|
||||||
<Button class="bg-primary">{i18n.localize(size)}</Button>
|
<Button class="bg-primary">{i18n.localize(size)}</Button>
|
||||||
{:else}
|
{:else}
|
||||||
<Button variant="secondary" onclick={() => ship.grid = size}>{i18n.localize(size)}</Button>
|
<Button variant="secondary" onmousedown={() => ship.grid = size}>{i18n.localize(size)}</Button>
|
||||||
{/if}
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
<Label for="gravity">{i18n.localize("gravity")}</Label>
|
<Label for="gravity">{i18n.localize("gravity")}</Label>
|
||||||
<Input type="number" step="0.01" id="gravity" bind:value={gravity}/>
|
<Input type="number" step="0.01" id="gravity" bind:value={gravity} onchange={(change) => {handleGravityChange(change)}}/>
|
||||||
<Label for="density">{i18n.localize("density")}</Label>
|
<Label for="density">{i18n.localize("density")}</Label>
|
||||||
<div id="density" class="flex gap-2">
|
<div id="density" class="flex gap-2">
|
||||||
{#each Object.values(CargoMaterial) as value}
|
{#each Object.values(CargoMaterial) as value}
|
||||||
{#if material === value}
|
{#if material === value}
|
||||||
<Button class="bg-primary">{i18n.localize(value.name)}</Button>
|
<Button class="bg-primary">{i18n.localize(value.name)}</Button>
|
||||||
{:else}
|
{:else}
|
||||||
<Button variant="secondary" onclick={() => material = value}>{i18n.localize(value.name)}</Button>
|
<Button variant="secondary" onmousedown={() => material = value}>{i18n.localize(value.name)}</Button>
|
||||||
{/if}
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
<Label for="atmosDensity">{i18n.localize("atmosDensity")}</Label>
|
<Atmosphere bind:value={atmosphericDensity} />
|
||||||
<Input type="number" step="0.01" id="atmosDensity" bind:value={atmosphericDensity}/>
|
|
||||||
</Card.Content>
|
</Card.Content>
|
||||||
</Card.Root>
|
</Card.Root>
|
||||||
<Card.Root>
|
<Card.Root>
|
||||||
|
@ -183,15 +193,7 @@
|
||||||
</Card.Header>
|
</Card.Header>
|
||||||
<Card.Content class="flex flex-col gap-3">
|
<Card.Content class="flex flex-col gap-3">
|
||||||
<Separator />
|
<Separator />
|
||||||
<div class="flex gap-2">
|
<WeightOutputSegment {i18n} maxWeight={maxWeight} maxVehicleWeight="{maxVehicleWeight}" />
|
||||||
<p>{i18n.localize("liftableVehcileWeight")}:</p>
|
|
||||||
{#if maxVehicleWeight < 0}
|
|
||||||
<p class="text-destructive">{weightConversion(i18n, maxVehicleWeight)}</p>
|
|
||||||
{:else}
|
|
||||||
<p>{weightConversion(i18n, maxVehicleWeight)}</p>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
<p>{i18n.localize("liftableWeight")}: {weightConversion(i18n, maxWeight)}</p>
|
|
||||||
<Separator />
|
<Separator />
|
||||||
<p>{i18n.localize("fuels")}:
|
<p>{i18n.localize("fuels")}:
|
||||||
{ship.getFuelTypes().map((fuel) => i18n.localize(fuel.name)).join(", ") }
|
{ship.getFuelTypes().map((fuel) => i18n.localize(fuel.name)).join(", ") }
|
||||||
|
|
|
@ -494,10 +494,10 @@ binary-extensions@^2.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522"
|
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522"
|
||||||
integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==
|
integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==
|
||||||
|
|
||||||
bits-ui@^0.21.8:
|
bits-ui@^0.21.9:
|
||||||
version "0.21.8"
|
version "0.21.9"
|
||||||
resolved "https://registry.yarnpkg.com/bits-ui/-/bits-ui-0.21.8.tgz#623127b87558c9943c00393cb5969c1ae7ca7cfa"
|
resolved "https://registry.yarnpkg.com/bits-ui/-/bits-ui-0.21.9.tgz#3e9ca44445a1f9a431783e2a7269de220f6dd3ec"
|
||||||
integrity sha512-fr++Gf//41w9/Td5r1SfaeA/XXv5YEOw3LFY7JVH+eAbi7RzNqf7Xy8BS/W8HXfRqlsu1ReFgZ7ZZ4DbrP4HwQ==
|
integrity sha512-tMoHi2QbsNKJsPDoXGi07OMx6F8LVMSNYMMcntFX4fPPvy+SJSeZYOKlBMmneiSg7smpWzg+h20q0q01OvyxZQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@internationalized/date" "^3.5.1"
|
"@internationalized/date" "^3.5.1"
|
||||||
"@melt-ui/svelte" "0.76.2"
|
"@melt-ui/svelte" "0.76.2"
|
||||||
|
|
Loading…
Reference in a new issue