@ui5/webcomponents-react
Version:
React Wrapper for UI5 Web Components and additional components
125 lines • 4.44 kB
JavaScript
import { useI18nBundle } from '@ui5/webcomponents-react-base';
import { useCallback, useEffect, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
import { DRAG_TO_RESIZE } from '../../i18n/i18n-defaults.js';
import { jsx as _jsx } from "react/jsx-runtime";
const isTouchEvent = (e, touchEvent) => {
if (e.type === touchEvent) {
return !(e.touches && e.touches.length > 1);
}
return false;
};
export const VerticalResizer = props => {
const {
analyticalTableRef,
dispatch,
extensionsHeight,
hasPopInColumns,
popInRowHeight,
rowsLength,
visibleRows,
handleOnLoadMore,
classNames
} = props;
const startY = useRef(null);
const verticalResizerRef = useRef(null);
const [resizerPosition, setResizerPosition] = useState(undefined);
const [isDragging, setIsDragging] = useState(false);
const [mountTouchEvents, setMountTouchEvents] = useState(false);
const i18nBundle = useI18nBundle('@ui5/webcomponents-react');
const handleResizeStart = useCallback(e => {
e.preventDefault();
const touchEvent = isTouchEvent(e, 'touchstart');
startY.current = touchEvent ? Math.round(e.touches[0].pageY) : e.pageY;
setMountTouchEvents(touchEvent);
setIsDragging(true);
}, []);
const handleMove = useCallback(e => {
setResizerPosition(prev => ({
...prev,
top: isTouchEvent(e, 'touchmove') ? Math.round(e.touches[0].pageY) : e.pageY
}));
}, [setResizerPosition]);
const handleResizeEnd = useCallback(e => {
setIsDragging(false);
const rowCount = Math.floor((analyticalTableRef.current.clientHeight + (isTouchEvent(e, 'touchend') ? Math.round(e.changedTouches[0].pageY) : e.pageY) - startY.current - extensionsHeight - 5 /*resizer height*/) / popInRowHeight);
if (hasPopInColumns) {
dispatch({
type: 'INTERACTIVE_ROWS_HAVE_POPIN',
payload: true
});
}
dispatch({
type: 'VISIBLE_ROWS',
payload: {
visibleRows: rowCount
}
});
}, [analyticalTableRef, dispatch, extensionsHeight, hasPopInColumns, popInRowHeight]);
useEffect(() => {
const removeEventListeners = () => {
if (mountTouchEvents) {
document.removeEventListener('touchmove', handleMove);
document.removeEventListener('touchend', handleResizeEnd);
} else {
document.removeEventListener('mouseup', handleResizeEnd);
document.removeEventListener('mousemove', handleMove);
}
};
if (isDragging) {
if (mountTouchEvents) {
document.addEventListener('touchmove', handleMove);
document.addEventListener('touchend', handleResizeEnd);
} else {
document.addEventListener('mousemove', handleMove);
document.addEventListener('mouseup', handleResizeEnd);
}
} else {
removeEventListeners();
}
return () => {
removeEventListeners();
};
}, [handleMove, handleResizeEnd, isDragging, mountTouchEvents]);
useEffect(() => {
const resizerPosTop = verticalResizerRef.current?.getBoundingClientRect()?.top + window.scrollY;
const resizerPosLeft = verticalResizerRef.current?.getBoundingClientRect()?.left + window.scrollX;
const resizerPosWidth = verticalResizerRef.current?.getBoundingClientRect()?.width;
if (!isDragging && resizerPosTop > 0) {
requestAnimationFrame(() => {
setResizerPosition({
left: resizerPosLeft,
top: resizerPosTop,
width: resizerPosWidth
});
});
}
}, [isDragging]);
const isInitial = useRef(true);
useEffect(() => {
if (!isInitial.current && rowsLength <= visibleRows) {
handleOnLoadMore({
type: 'tableGrow'
});
}
isInitial.current = false;
}, [handleOnLoadMore, rowsLength, visibleRows]);
return /*#__PURE__*/_jsx("div", {
"aria-hidden": "true",
className: classNames.verticalResizerContainer,
ref: verticalResizerRef,
onMouseDown: handleResizeStart,
onTouchStart: handleResizeStart,
role: "separator",
title: i18nBundle.getText(DRAG_TO_RESIZE),
children: resizerPosition && isDragging && /*#__PURE__*/createPortal(/*#__PURE__*/_jsx("div", {
className: classNames.verticalResizer,
style: {
top: resizerPosition.top,
left: resizerPosition.left,
width: resizerPosition.width
}
}), document.body)
});
};
VerticalResizer.displayName = 'VerticalResizer';