UNPKG

@brizy/ui

Version:
63 lines (62 loc) 3.73 kB
import { classNames } from "../classNamesFn"; import React, { useCallback, useEffect, useMemo, useRef, useState, } from "react"; import Draggable from "react-draggable"; import { Loading } from ".."; import { getSizeProperties } from "./utils"; import { BRZ_PREFIX } from "../constants"; import { useTranslation } from "../utils/localization/useTranslation"; export const ImagePointer = ({ value, src, errorMessage, size = "middle", maxBy = "both", onChange, onError, }) => { const { t } = useTranslation(); const [imageWidth, setImageWidth] = useState(0); const [imageHeight, setImageHeight] = useState(0); const fromPercentageToPosition = useMemo(() => ({ x: (imageWidth * value.x) / 100, y: (imageHeight * value.y) / 100, }), [imageHeight, imageWidth, value]); const [position, setPosition] = useState(fromPercentageToPosition); const [isError, setIsError] = useState(false); const node = useRef(null); const draggable = useRef(null); const handleChange = useCallback(({ x, y }) => { const xPercentage = x / (imageWidth / 100); const yPercentage = y / (imageHeight / 100); const xResult = xPercentage < 0 ? 0 : xPercentage > 100 ? 100 : xPercentage; const yResult = yPercentage < 0 ? 0 : yPercentage > 100 ? 100 : yPercentage; onChange === null || onChange === void 0 ? void 0 : onChange({ x: xResult, y: yResult }); }, [imageHeight, imageWidth, onChange]); const onStop = useCallback(() => { handleChange(position); }, [handleChange, position]); const handleDrag = useCallback((_, data) => { setPosition(pos => ({ x: pos.x + data.deltaX, y: pos.y + data.deltaY })); }, [setPosition]); const _onClick = useCallback((event) => { if (node.current) { const nodeRect = node.current.getBoundingClientRect(); handleChange({ x: event.clientX - nodeRect.x, y: event.clientY - nodeRect.y }); } }, [handleChange, node]); const handleLoad = useCallback((e) => { const el = e.target; setImageWidth(el.clientWidth); setImageHeight(el.clientHeight); }, [setImageWidth, setImageHeight]); const handleError = useCallback(() => { setIsError(true); onError === null || onError === void 0 ? void 0 : onError(); }, [setIsError, onError]); const className = classNames()("image-pointer__container", { "image-pointer__hidden": !imageHeight && !imageWidth && !isError, }); useEffect(() => { setPosition(fromPercentageToPosition); }, [setPosition, fromPercentageToPosition]); return (React.createElement("div", { className: `${BRZ_PREFIX}-image-pointer`, style: getSizeProperties({ size, maxBy }) }, isError ? (React.createElement("div", { className: `${BRZ_PREFIX}-image-pointer__error` }, errorMessage !== null && errorMessage !== void 0 ? errorMessage : t("Upload image error"))) : (React.createElement(React.Fragment, null, !imageHeight && !imageWidth && (React.createElement("div", { className: `${BRZ_PREFIX}-image-pointer__loading-container` }, React.createElement(Loading, null))), React.createElement("div", { className: className, ref: node, onClick: _onClick }, React.createElement(Draggable, { bounds: "parent", nodeRef: draggable, position: fromPercentageToPosition, onDrag: handleDrag, onStop: onStop }, React.createElement("div", { className: `${BRZ_PREFIX}-image-pointer__draggable`, ref: draggable })), React.createElement("div", { className: `${BRZ_PREFIX}-image-pointer__children` }, React.createElement("img", { onError: handleError, onLoad: handleLoad, src: src }))))))); };