A beatifully animated locking toggle.
<script lang="ts"> import { NumberInput, ToggleLock } from '@leon8ix/jhana-ui'; let value = $state(1); let disabled = $state(false); </script> <div class="input-group"> <NumberInput bind:value class="w-sm" {disabled} /> <ToggleLock bind:checked={disabled} /> </div>
A beatifully animated linking toggle. Specifically intended for locking an aspect ratio.
<script lang="ts"> import { NumberInput, ToggleLink } from '@leon8ix/jhana-ui'; import { rnd } from '@leon8ix/utils'; import type { InputEvent } from '@leon8ix/utils/dom'; let v1: number | null = $state(1); let v2: number | null = $state(2); let ratio: number | null = $state(null); function link(e: InputEvent) { if (!e.currentTarget.checked) ratio = null; else ratio = (v1 || (v1 = 1)) / (v2 || (v2 = 1)); } function getNum(e: InputEvent) { const val = e.currentTarget.value; if (!val.length) return null; const num = Number(val); return isNaN(num) ? null : num; } function setV1(e: InputEvent) { const val = getNum(e); v1 = val; if (ratio) v2 = val ? val / ratio : null; } function setV2(e: InputEvent) { const val = getNum(e); v2 = val; if (ratio) v1 = val ? val * ratio : null; } </script> <div class="input-group"> <NumberInput value={v1 && rnd(v1, 4)} oninput={setV1} class="w-md" /> <ToggleLink checked={!!ratio} oninput={link} /> <NumberInput value={v2 && rnd(v2, 4)} oninput={setV2} class="w-md" /> </div>
Here you can see, how you might pull all of this together. This sample does not implement the logic. It only demonstartes the structure and classes.
<script lang="ts"> import { NumberInput, ToggleLink, ToggleLock } from '@leon8ix/jhana-ui'; let linkBleed = $state(true); let linkSize = $state(true); let locked = $state(false); type Config = Record<'bleed' | 'bleedX' | 'bleedY' | 'scale' | 'width' | 'height', number | null>; let config: Config = $state({ bleed: 2, bleedX: 2, bleedY: 2, scale: 1, width: 100, height: 100 }); </script> <div class="dialog space-y-sm" style="width: fit-content"> <h3 class="h4">Scaling and Size</h3> <fieldset class="input-group"> <NumberInput label="Bleed" bind:value={config.bleed} class="w-md" /> <ToggleLock bind:checked={locked} /> <NumberInput label="X-Bleed" bind:value={config.bleedX} class="w-md" /> <ToggleLink bind:checked={linkBleed} /> <NumberInput label="Y-Bleed" bind:value={config.bleedY} class="w-md" /> </fieldset> <fieldset class="input-group"> <NumberInput label="Scale" bind:value={config.scale} class="w-md" step="0.1" min="0" /> <ToggleLock checked={!locked} oninput={() => (locked = !locked)} /> <NumberInput label="Width" bind:value={config.width} class="w-md" /> <ToggleLink bind:checked={linkSize} /> <NumberInput label="Height" bind:value={config.height} class="w-md" /> </fieldset> </div>