61 lines
2.1 KiB
Vue
61 lines
2.1 KiB
Vue
<script setup lang="ts">
|
|
import type { VarSlider } from '~/composables/useVarSliders'
|
|
|
|
/* the sliders one row wears: each free variable gets a line — the name in
|
|
the maths' own face, a drag for the rough and a field for the fine.
|
|
Normally hung just beneath the row; a row that only declares a variable
|
|
(the "k" or "k = 3" that creates one) instead wears the slider in place of
|
|
its text once the field rests — pass `inline` to lay it inside the row,
|
|
and `inputFor` (the id of that declaration's field, kept mounted behind
|
|
the slider) so a click on the name wakes the text to edit it again.
|
|
Shared by both calculators; the logic behind the values lives in
|
|
useVarSliders. */
|
|
defineProps<{ sliders: VarSlider[]; inline?: boolean; inputFor?: string }>()
|
|
|
|
const emit = defineEmits<{ set: [name: string, value: number] }>()
|
|
|
|
/* how finely a slider moves, dragged or typed */
|
|
const STEP = 0.1
|
|
|
|
const { t } = useI18n()
|
|
</script>
|
|
|
|
<template>
|
|
<ul
|
|
v-if="sliders.length"
|
|
class="calc-vars"
|
|
:class="{ 'is-inline': inline }"
|
|
:aria-label="t('calc.variablesPanel')"
|
|
>
|
|
<li v-for="s in sliders" :key="s.name" class="calc-var">
|
|
<!-- a declaration row's slider wears its name as a door back to the
|
|
field behind it: clicking it wakes "k = 3" to be edited again -->
|
|
<label
|
|
v-if="inputFor"
|
|
class="calc-var-name editable"
|
|
:for="inputFor"
|
|
:title="t('calc.editVariable', { name: s.name })"
|
|
>{{ s.name }}</label>
|
|
<span v-else class="calc-var-name">{{ s.name }}</span>
|
|
<input
|
|
type="range"
|
|
class="calc-var-range"
|
|
:min="s.min"
|
|
:max="s.max"
|
|
:step="STEP"
|
|
:value="s.value"
|
|
:aria-label="t('calc.variableValue', { name: s.name })"
|
|
@input="emit('set', s.name, ($event.target as HTMLInputElement).valueAsNumber)"
|
|
/>
|
|
<input
|
|
type="number"
|
|
class="calc-var-number"
|
|
:step="STEP"
|
|
:value="s.value"
|
|
:aria-label="t('calc.variableValue', { name: s.name })"
|
|
@change="emit('set', s.name, ($event.target as HTMLInputElement).valueAsNumber)"
|
|
/>
|
|
</li>
|
|
</ul>
|
|
</template>
|