mirror of
https://github.com/ToolJet/ToolJet
synced 2026-05-24 09:28:31 +00:00
113 lines
4 KiB
JavaScript
113 lines
4 KiB
JavaScript
/* eslint-disable import/no-unresolved */
|
|
import React, { useRef, useEffect, useState } from 'react';
|
|
import LazyLoad from 'react-lazyload';
|
|
import { TransformWrapper, TransformComponent } from 'react-zoom-pan-pinch';
|
|
|
|
export const Image = function Image({ component, height, properties, styles, fireEvent, width }) {
|
|
const { source, loadingState, alternativeText, zoomButtons } = properties;
|
|
const { visibility, disabledState, borderType, backgroundColor, padding, imageFit } = 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);
|
|
|
|
function Placeholder() {
|
|
return <div className="skeleton-image" style={{ objectFit: 'contain', height }}></div>;
|
|
}
|
|
useEffect(() => {
|
|
setImageOffset(computeOffset());
|
|
}, [imageRef]);
|
|
|
|
function computeOffset() {
|
|
if (imageRef.current) {
|
|
const clientRect = imageRef.current.getBoundingClientRect();
|
|
const layoutHeightWithOffset = clientRect.top + clientRect.height;
|
|
return layoutHeightWithOffset - document.documentElement.clientHeight;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
return (
|
|
<div
|
|
data-disabled={disabledState}
|
|
style={{
|
|
display: widgetVisibility ? 'flex' : 'none',
|
|
justifyContent: 'center',
|
|
}}
|
|
ref={imageRef}
|
|
className="image-widget-wrapper"
|
|
>
|
|
{imageRef.current && (
|
|
<LazyLoad
|
|
offset={imageOffset > 0 ? imageOffset : 0}
|
|
height={height}
|
|
placeholder={<Placeholder />}
|
|
debounce={500}
|
|
>
|
|
{loadingState === true ? (
|
|
<center>
|
|
<div className="spinner-border " role="status"></div>
|
|
</center>
|
|
) : zoomButtons ? (
|
|
<>
|
|
<TransformWrapper>
|
|
{({ zoomIn, zoomOut }) => (
|
|
<>
|
|
<React.Fragment>
|
|
<TransformComponent>
|
|
<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',
|
|
}}
|
|
height={height}
|
|
onClick={() => fireEvent('onClick')}
|
|
alt={alternativeText}
|
|
width={width}
|
|
/>
|
|
</TransformComponent>
|
|
</React.Fragment>
|
|
{zoomButtons && (
|
|
<div className="zoom-button-wrapper">
|
|
<button className="btn zoom-buttons " onClick={() => zoomIn()}>
|
|
+
|
|
</button>
|
|
<button className="btn zoom-buttons" onClick={() => zoomOut()}>
|
|
-
|
|
</button>
|
|
</div>
|
|
)}
|
|
</>
|
|
)}
|
|
</TransformWrapper>
|
|
</>
|
|
) : (
|
|
<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',
|
|
}}
|
|
height={height}
|
|
onClick={() => fireEvent('onClick')}
|
|
alt={alternativeText}
|
|
width={width}
|
|
/>
|
|
)}
|
|
</LazyLoad>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|