mirror of
https://github.com/ToolJet/ToolJet
synced 2026-05-24 09:28:31 +00:00
* feat :: temp commit added box shadow for freq used components * fix :: box shadow for all components * cleanup * review :: changes , sending boz shadow with styles * fix :: apply box shadow to the item instead of container * fix :: daterange picker shadows
157 lines
4.6 KiB
JavaScript
157 lines
4.6 KiB
JavaScript
/* eslint-disable import/no-unresolved */
|
|
import React, { useRef, useEffect, useState } from 'react';
|
|
import LazyLoad, { forceCheck } from 'react-lazyload';
|
|
import { TransformWrapper, TransformComponent } from 'react-zoom-pan-pinch';
|
|
|
|
export const Image = function Image({
|
|
component,
|
|
height,
|
|
properties,
|
|
styles,
|
|
fireEvent,
|
|
width,
|
|
parentId = null,
|
|
dataCy,
|
|
}) {
|
|
const { source, loadingState, alternativeText, zoomButtons, rotateButton } = properties;
|
|
const { visibility, disabledState, borderType, backgroundColor, padding, imageFit, boxShadow } = styles;
|
|
const {
|
|
definition: { events },
|
|
} = component;
|
|
const hasOnClickEvent = events.some((event) => event.eventId === 'onClick');
|
|
const widgetVisibility = visibility ?? true;
|
|
const imageRef = useRef(null);
|
|
const [imageOffset, setImageOffset] = useState(0);
|
|
const [rotation, setRotation] = useState(0);
|
|
const [zoomReset, setZoomReset] = useState(false);
|
|
|
|
function Placeholder() {
|
|
return <div className="skeleton-image" style={{ objectFit: 'contain', height }}></div>;
|
|
}
|
|
useEffect(() => {
|
|
if (parentId === null) {
|
|
setImageOffset(computeOffset());
|
|
}
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [imageRef]);
|
|
|
|
useEffect(() => {
|
|
setRotation(0);
|
|
setZoomReset(true);
|
|
}, [source]);
|
|
|
|
function computeOffset() {
|
|
if (imageRef.current) {
|
|
const clientRect = imageRef.current.getBoundingClientRect();
|
|
const layoutHeightWithOffset = clientRect.top + clientRect.height;
|
|
return layoutHeightWithOffset - document.documentElement.clientHeight;
|
|
}
|
|
return 0;
|
|
}
|
|
useEffect(() => {
|
|
forceCheck();
|
|
}, [visibility]);
|
|
|
|
const rotateImage = () => setRotation((prevValue) => (prevValue === 270 ? 0 : prevValue + 90));
|
|
|
|
const renderImage = () => (
|
|
<img
|
|
src={source}
|
|
className={`zoom-image-wrap ${borderType !== 'none' ? borderType : ''}`}
|
|
style={{
|
|
backgroundColor,
|
|
padding: Number.parseInt(padding),
|
|
objectFit: imageFit ? imageFit : 'contain',
|
|
cursor: hasOnClickEvent ? 'pointer' : 'inherit',
|
|
pointerEvents: 'auto',
|
|
width,
|
|
height,
|
|
transform: `rotate(${rotation}deg)`,
|
|
}}
|
|
height={height}
|
|
onClick={() => fireEvent('onClick')}
|
|
alt={alternativeText}
|
|
width={width}
|
|
/>
|
|
);
|
|
|
|
const resetZoom = (resetTransform) => {
|
|
setZoomReset(false);
|
|
resetTransform();
|
|
};
|
|
|
|
const renderImageContainer = () => {
|
|
return (
|
|
<>
|
|
{loadingState === true ? (
|
|
<center>
|
|
<div className="spinner-border " role="status" data-cy={dataCy}></div>
|
|
</center>
|
|
) : zoomButtons ? (
|
|
<TransformWrapper>
|
|
{({ zoomIn, zoomOut, resetTransform }) => (
|
|
<>
|
|
{zoomReset && resetZoom(resetTransform)}
|
|
<TransformComponent>{renderImage()}</TransformComponent>
|
|
{zoomButtons && (
|
|
<div className="zoom-button-wrapper">
|
|
{rotateButton && (
|
|
<button className="btn zoom-buttons" onClick={rotateImage}>
|
|
<span>↻</span>
|
|
</button>
|
|
)}
|
|
<button className="btn zoom-buttons" onClick={() => zoomIn()}>
|
|
+
|
|
</button>
|
|
<button className="btn zoom-buttons" onClick={() => zoomOut()}>
|
|
-
|
|
</button>
|
|
</div>
|
|
)}
|
|
</>
|
|
)}
|
|
</TransformWrapper>
|
|
) : (
|
|
<>
|
|
{rotateButton && (
|
|
<div className="zoom-button-wrapper" style={{ zIndex: 1 }}>
|
|
<button className="btn zoom-buttons" onClick={rotateImage}>
|
|
<span>↻</span>
|
|
</button>
|
|
</div>
|
|
)}
|
|
{renderImage()}
|
|
</>
|
|
)}
|
|
</>
|
|
);
|
|
};
|
|
|
|
return (
|
|
<div
|
|
data-disabled={disabledState}
|
|
data-cy={`draggable-widget-${String(component.name).toLowerCase()}`}
|
|
style={{
|
|
display: widgetVisibility ? 'flex' : 'none',
|
|
justifyContent: 'center',
|
|
boxShadow,
|
|
}}
|
|
ref={imageRef}
|
|
className="image-widget-wrapper"
|
|
>
|
|
{imageRef.current && parentId === null ? (
|
|
<LazyLoad
|
|
offset={imageOffset > 0 ? imageOffset : 0}
|
|
height={height}
|
|
placeholder={<Placeholder />}
|
|
debounce={500}
|
|
scrollContainer={'.canvas-container'}
|
|
>
|
|
{renderImageContainer()}
|
|
</LazyLoad>
|
|
) : (
|
|
imageRef.current && renderImageContainer()
|
|
)}
|
|
</div>
|
|
);
|
|
};
|