@wix/design-system
Version:
@wix/design-system
84 lines • 3.12 kB
JavaScript
import { useCallback, useRef } from 'react';
import { useEventCallback } from '../../common/useEventCallback/useEventCallback';
import { angleLimits } from '../AngleInput.constants';
export const useAngleInput = ({ onChange, onPointerDown, onPointerUp, onFocus, onBlur, step, }) => {
const rootRef = useRef(null);
const calculateAngleFromEvent = useCallback((clientX, clientY) => {
const rootElement = rootRef.current;
if (!rootElement)
return;
const { left, top, width, height } = rootElement.getBoundingClientRect();
const centerX = left + width / 2;
const centerY = top + height / 2;
const dx = clientX - centerX;
const dy = clientY - centerY;
const rawAngle = Math.atan2(dx, -dy) * (180 / Math.PI);
const normalizedAngle = normalizeAngle(rawAngle);
return (Math.round(normalizedAngle / step) * step) % 360;
}, [step]);
const updateAngle = useEventCallback((clientX, clientY) => {
const angle = calculateAngleFromEvent(clientX, clientY);
if (angle !== undefined)
onChange(angle);
});
const handlePointerDown = useEventCallback((event) => {
event.currentTarget.setPointerCapture(event.pointerId);
onPointerDown?.();
updateAngle(event.clientX, event.clientY);
});
const handlePointerMove = useEventCallback((event) => {
if (event.currentTarget.hasPointerCapture(event.pointerId)) {
updateAngle(event.clientX, event.clientY);
}
});
const handlePointerUp = useEventCallback((event) => {
onPointerUp?.();
if (event.currentTarget.hasPointerCapture(event.pointerId)) {
event.currentTarget.releasePointerCapture(event.pointerId);
}
});
const handleInputChange = useEventCallback((event) => {
onChange(normalizeAngle(Number(event.target.value)));
});
const handleKeyboardEvent = useEventCallback((event) => {
const { key, currentTarget } = event;
const currentAngle = Number(currentTarget.value);
let newAngle = currentAngle;
switch (key) {
case 'ArrowUp':
case 'ArrowRight':
case 'PageUp':
newAngle += step;
break;
case 'ArrowDown':
case 'ArrowLeft':
case 'PageDown':
newAngle -= step;
break;
default:
return;
}
if (newAngle > angleLimits.max || newAngle < angleLimits.min) {
event.preventDefault();
onChange(normalizeAngle(newAngle));
}
});
const handleFocus = useEventCallback(() => {
onFocus?.();
});
const handleBlur = useEventCallback(() => {
onBlur?.();
});
return {
rootRef,
handlePointerDown,
handlePointerUp,
handlePointerMove,
handleInputChange,
handleKeyboardEvent,
handleFocus,
handleBlur,
};
};
const normalizeAngle = (angle) => (angle + 360) % 360;
//# sourceMappingURL=useAngleInput.js.map