Phase 2: core converter, live conversion, URL state, highlight interaction

This commit is contained in:
Falkan
2026-03-16 21:34:16 -04:00
parent 65f8bc1b9f
commit 8f835c35d2
9 changed files with 430 additions and 1 deletions

View File

@@ -0,0 +1,59 @@
<script lang="ts">
import type { Unit, ResultItem } from '$lib/types';
import { MIN_COLUMN_WIDTH, GRID_GAP } from '$lib/config';
import UnitInput from './UnitInput.svelte';
import UnitDropdown from './UnitDropdown.svelte';
import ConversionResult from './ConversionResult.svelte';
/**
* ConverterCard — groups UnitInput + UnitDropdown + results grid + hotkey hint.
* Emits events upward; does NOT contain NL input (Phase 3).
*/
let {
units,
inputValue,
fromUnitId,
highlightedUnitId,
results,
oninputchange,
onunitchange,
onhighlight,
onsetinput
}: {
units: Unit[];
inputValue: number;
fromUnitId: string;
highlightedUnitId: string | null;
results: ResultItem[];
oninputchange: (v: number) => void;
onunitchange: (id: string) => void;
onhighlight: (id: string) => void;
onsetinput: (id: string) => void;
} = $props();
const gridStyle = `--min-col-width: ${MIN_COLUMN_WIDTH}; --grid-gap: ${GRID_GAP};`;
</script>
<article>
<div class="converter-controls">
<UnitInput value={inputValue} onchange={oninputchange} />
<UnitDropdown {units} value={fromUnitId} onchange={onunitchange} />
</div>
<div class="results-grid" style={gridStyle}>
{#each results as item (item.unit.id)}
<ConversionResult
value={item.convertedValue}
unit={item.unit}
highlighted={item.unit.id === highlightedUnitId}
onclick={() => onhighlight(item.unit.id)}
onshiftclick={() => onsetinput(item.unit.id)}
/>
{/each}
</div>
<p class="hotkey-hint">
<small>Click a result to highlight it · Shift+click to use it as input</small>
</p>
</article>