ratio-lock
Version:
A TypeScript library for managing n numbers with locked ratios. When the ratio is locked, changing one value automatically adjusts all other values to maintain their proportional relationships.
41 lines • 2.14 kB
JavaScript
import { useCallback, useState, useMemo, useEffect, useRef } from 'react';
import { useWatch } from 'react-hook-form';
import { RatioLock } from '../ratio-lock.js';
import { parseNumber } from './parse-number.js';
import { syncRatioValues } from './sync-ratio-values.js';
import { createFieldChangeHandler } from './create-field-change-handler.js';
import { createFieldsObject } from './create-fields-object.js';
/**
* React Hook Form integration for ratio-locked fields
* @param options - Configuration options including control, setValue, and field names
* @returns Object with field props and lock controls
*/
export function useRatioLockField(options) {
const { control, setValue: setFormValue, names, precision } = options;
const watchedValues = useWatch({ control, name: names });
const [ratioLock] = useState(() => {
const initialValues = watchedValues.map((v, i) => parseNumber(v, names[i]));
return new RatioLock(initialValues, { precision });
});
const [isLocked, setIsLocked] = useState(false);
const prevValuesRef = useRef(watchedValues.map((v, i) => parseNumber(v, names[i])));
useEffect(() => {
prevValuesRef.current = syncRatioValues(watchedValues, prevValuesRef.current, names, ratioLock, setFormValue);
}, [watchedValues, ratioLock, names, setFormValue]);
const lock = useCallback(() => {
ratioLock.lock();
setIsLocked(true);
}, [ratioLock]);
const unlock = useCallback(() => {
ratioLock.unlock();
setIsLocked(false);
}, [ratioLock]);
const toggle = useCallback(() => {
ratioLock.toggle();
setIsLocked(ratioLock.isLocked());
}, [ratioLock]);
const createOnChange = useCallback((index) => createFieldChangeHandler(index, ratioLock, names, setFormValue), [ratioLock, names, setFormValue]);
const fields = useMemo(() => createFieldsObject(names, watchedValues, createOnChange), [names, watchedValues, createOnChange]);
return useMemo(() => ({ fields, isLocked, lock, unlock, toggle }), [fields, isLocked, lock, unlock, toggle]);
}
//# sourceMappingURL=use-ratio-lock-field.js.map