/** * There are similar functions to those in this module in vue-use, but they only work one-way. * Unlike vue-use, these composables return refs which can be set. */ import { type MaybeRefOrGetter, toValue } from "@vueuse/core"; import { computed, type Ref } from "vue"; /** * Wraps a number ref, restricting it's values to a given range * * @param ref ref containing a number to wrap * @param min lowest possible value of range * @param max highest possible value of range * @returns clamped ref */ export function useClamp(ref: Ref, min: MaybeRefOrGetter, max: MaybeRefOrGetter): Ref { const clamp = (value: number) => { return Math.min(Math.max(value, toValue(min)), toValue(max)); }; const clampedRef = computed({ get: () => clamp(ref.value), set: (value) => (ref.value = clamp(value)), }); return clampedRef; } /** * Wraps a number ref, restricting it's values to align to a given step size * * @param ref ref containing a number to wrap * @param [stepSize = 1] size of steps to restrict value to. defaults to 1 * @returns wrapped red */ export function useStep(ref: Ref, stepSize: MaybeRefOrGetter = 1): Ref { const step = (value: number) => { const stepSizeValue = toValue(stepSize); return Math.round(value / stepSizeValue) * stepSizeValue; }; const steppedRef = computed({ get: () => step(ref.value), set: (value) => (ref.value = step(value)), }); return steppedRef; }