Range 2D
Two-axis range input with a draggable handle, arrow-key nudging, and an API to map click positions into value space. Works with any handle UI you render through a snippet.
Click anywhere in the box to move the handle (using `coordsToValue`), drag to update both axes, or press arrow keys while the handle is focused to nudge values.
Usage
<script lang="ts">
import { Range2D } from '@obelus/trioxide';
let x = $state(0.25);
let y = $state(0.75);
</script>
<Range2D bind:x bind:y min-x={-1} max-x={1} min-y={0} max-y={10} class="h-48 rounded-sm border">
{#snippet Handle(bindings)}
<button class="h-3 w-3 rounded-full" {...bindings}></button>
{/snippet}
</Range2D> Props
x/bind:x,y/bind:y: numeric values mapped to the 2D plane; defaults to0.min-x,max-x,min-y,max-y: bounds for each axis; values are clamped on drag, click, or keyboard.Handle: is the snippet that renders the draggable element; spreadbindingsto wire up drag/keyboard and positioning.api/bind:api: exposescoordsToValue(clientX, clientY)which converts a viewport point to clamped{ x, y }in your value space useful for programmatic updates or overlay clicks.- Remaining
HTMLDivElementprops apply to the outer container (e.g.,class,style,aria-*).