mirror of
https://github.com/robonen/tools.git
synced 2026-03-20 10:54:44 +00:00
feat(packages/vue): add useClamp composable
This commit is contained in:
60
packages/vue/src/composables/useClamp/index.test.ts
Normal file
60
packages/vue/src/composables/useClamp/index.test.ts
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import { ref, readonly, computed } from 'vue';
|
||||||
|
import { describe, it, expect } from 'vitest';
|
||||||
|
import { useClamp } from '.';
|
||||||
|
|
||||||
|
describe('useClamp', () => {
|
||||||
|
it('non-reactive values should be clamped', () => {
|
||||||
|
const clampedValue = useClamp(10, 0, 5);
|
||||||
|
|
||||||
|
expect(clampedValue.value).toBe(5);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('clamp the value within the given range', () => {
|
||||||
|
const value = ref(10);
|
||||||
|
const clampedValue = useClamp(value, 0, 5);
|
||||||
|
|
||||||
|
expect(clampedValue.value).toBe(5);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('clamp the value within the given range using functions', () => {
|
||||||
|
const value = ref(10);
|
||||||
|
const clampedValue = useClamp(value, () => 0, () => 5);
|
||||||
|
|
||||||
|
expect(clampedValue.value).toBe(5);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('clamp readonly values', () => {
|
||||||
|
const computedValue = computed(() => 10);
|
||||||
|
const readonlyValue = readonly(ref(10));
|
||||||
|
const clampedValue1 = useClamp(computedValue, 0, 5);
|
||||||
|
const clampedValue2 = useClamp(readonlyValue, 0, 5);
|
||||||
|
|
||||||
|
expect(clampedValue1.value).toBe(5);
|
||||||
|
expect(clampedValue2.value).toBe(5);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('update the clamped value when the original value changes', () => {
|
||||||
|
const value = ref(10);
|
||||||
|
const clampedValue = useClamp(value, 0, 5);
|
||||||
|
value.value = 3;
|
||||||
|
|
||||||
|
expect(clampedValue.value).toBe(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('update the clamped value when the min or max changes', () => {
|
||||||
|
const value = ref(10);
|
||||||
|
const min = ref(0);
|
||||||
|
const max = ref(5);
|
||||||
|
const clampedValue = useClamp(value, min, max);
|
||||||
|
|
||||||
|
expect(clampedValue.value).toBe(5);
|
||||||
|
|
||||||
|
max.value = 15;
|
||||||
|
|
||||||
|
expect(clampedValue.value).toBe(10);
|
||||||
|
|
||||||
|
min.value = 11;
|
||||||
|
|
||||||
|
expect(clampedValue.value).toBe(11);
|
||||||
|
});
|
||||||
|
});
|
||||||
37
packages/vue/src/composables/useClamp/index.ts
Normal file
37
packages/vue/src/composables/useClamp/index.ts
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import { clamp, isFunction } from '@robonen/stdlib';
|
||||||
|
import { computed, isReadonly, ref, toValue, type ComputedRef, type MaybeRef, type MaybeRefOrGetter, type WritableComputedRef } from 'vue';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name useClamp
|
||||||
|
* @category Math
|
||||||
|
* @description Clamps a value between a minimum and maximum value
|
||||||
|
*
|
||||||
|
* @param {MaybeRefOrGetter<number>} value The value to clamp
|
||||||
|
* @param {MaybeRefOrGetter<number>} min The minimum value
|
||||||
|
* @param {MaybeRefOrGetter<number>} max The maximum value
|
||||||
|
* @returns {ComputedRef<number>} The clamped value
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const value = ref(10);
|
||||||
|
* const clampedValue = useClamp(value, 0, 5);
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const value = ref(10);
|
||||||
|
* const clampedValue = useClamp(value, () => 0, () => 5);
|
||||||
|
*/
|
||||||
|
export function useClamp(value: MaybeRef<number>, min: MaybeRefOrGetter<number>, max: MaybeRefOrGetter<number>): WritableComputedRef<number>;
|
||||||
|
export function useClamp(value: MaybeRefOrGetter<number>, min: MaybeRefOrGetter<number>, max: MaybeRefOrGetter<number>): ComputedRef<number> {
|
||||||
|
if (isFunction(value) || isReadonly(value))
|
||||||
|
return computed(() => clamp(toValue(value), toValue(min), toValue(max)));
|
||||||
|
|
||||||
|
const _value = ref(value);
|
||||||
|
|
||||||
|
return computed<number>({
|
||||||
|
get() {
|
||||||
|
return clamp(_value.value, toValue(min), toValue(max));
|
||||||
|
},
|
||||||
|
set(newValue) {
|
||||||
|
_value.value = clamp(newValue, toValue(min), toValue(max));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user