UNPKG

@syncfusion/react-base

Version:

A common package of core React base, methods and class definitions

161 lines (160 loc) 6.28 kB
import { select } from './dom'; import { isNullOrUndefined } from './util'; let left; let top; let width; let height; /** * Sets the permitted drag area boundaries based on the defined dragArea. * * @private * @param {HTMLElement | string} dragArea - The element or selector string defining the drag area * @param {Element} helperElement - The helper element used in dragging * @param {PositionCoordinates} borderWidth - The border width of the drag area * @param {PositionCoordinates} padding - The padding of the drag area * @param {PositionCoordinates} dragLimit - The object to store the calculated drag limits * @returns {void} */ export function setDragArea(dragArea, helperElement, borderWidth, padding, dragLimit) { let eleWidthBound; let eleHeightBound; let top = 0; let left = 0; let ele; const type = typeof dragArea; if (type === 'string') { ele = select(dragArea); } else { ele = dragArea; } if (ele) { const elementArea = ele.getBoundingClientRect(); eleWidthBound = ele.scrollWidth ? ele.scrollWidth : elementArea.right - elementArea.left; eleHeightBound = ele.scrollHeight ? (dragArea && !isNullOrUndefined(helperElement) && helperElement.classList.contains('sf-treeview')) ? ele.clientHeight : ele.scrollHeight : elementArea.bottom - elementArea.top; const keys = ['Top', 'Left', 'Bottom', 'Right']; const styles = getComputedStyle(ele); for (let i = 0; i < keys.length; i++) { const key = keys[parseInt(i.toString(), 10)]; const tborder = styles['border' + key + 'Width']; const tpadding = styles['padding' + key]; const lowerKey = key.toLowerCase(); borderWidth[`${lowerKey}`] = isNaN(parseFloat(tborder)) ? 0 : parseFloat(tborder); padding[`${lowerKey}`] = isNaN(parseFloat(tpadding)) ? 0 : parseFloat(tpadding); } if (dragArea && !isNullOrUndefined(helperElement) && helperElement.classList.contains('sf-treeview')) { top = elementArea.top + document.scrollingElement.scrollTop; } else { top = elementArea.top; } left = elementArea.left; dragLimit.left = left + borderWidth.left + padding.left; dragLimit.top = ele.offsetTop + borderWidth.top + padding.top; dragLimit.right = left + eleWidthBound - (borderWidth.right + padding.right); dragLimit.bottom = top + eleHeightBound - (borderWidth.bottom + padding.bottom); } } /** * Retrieves the document's full height or width, considering the scroll and offset values. * * @private * @param {string} str - The dimension type ('Height' or 'Width') to calculate. * @returns {number} - The maximum value across scroll, offset, and client dimensions. */ export function getDocumentWidthHeight(str) { const docBody = document.body; const docEle = document.documentElement; return Math.max(docBody['scroll' + str], docEle['scroll' + str], docBody['offset' + str], docEle['offset' + str], docEle['client' + str]); } /** * Determines if a given element is within the bounds of the viewport. * * @private * @param {HTMLElement} el - The element to check. * @returns {boolean} - True if the element is in the viewport, false otherwise. */ export function elementInViewport(el) { top = el.offsetTop; left = el.offsetLeft; width = el.offsetWidth; height = el.offsetHeight; while (el.offsetParent) { el = el.offsetParent; top += el.offsetTop; left += el.offsetLeft; } return (top >= window.pageYOffset && left >= window.pageXOffset && (top + height) <= (window.pageYOffset + window.innerHeight) && (left + width) <= (window.pageXOffset + window.innerWidth)); } /** * Gets the coordinates of a mouse or touch event. * * @private * @param {MouseEvent | TouchEvent} evt - The event object. * @returns {Coordinates} - The x and y coordinates of the page and client. */ export function getCoordinates(evt) { if (evt.type.indexOf('touch') > -1) { return evt.changedTouches[0]; } return evt; } /** * Calculates the parent position of the element relative to the document. * * @private * @param {Element} ele - The element for which the parent position is calculated. * @returns {IPosition} - The calculated left and top position. */ export function calculateParentPosition(ele) { if (isNullOrUndefined(ele)) { return { left: 0, top: 0 }; } const rect = ele.getBoundingClientRect(); const style = getComputedStyle(ele); return { left: (rect.left + window.pageXOffset) - parseInt(style.marginLeft, 10), top: (rect.top + window.pageYOffset) - parseInt(style.marginTop, 10) }; } /** * Retrieves all elements from a point defined by event coordinates. * * @private * @param {MouseEvent | TouchEvent} evt - The event object containing coordinates. * @returns {Element[]} - An array of elements located at the event's point. */ export function getPathElements(evt) { const elementTop = evt.clientX > 0 ? evt.clientX : 0; const elementLeft = evt.clientY > 0 ? evt.clientY : 0; return document.elementsFromPoint(elementTop, elementLeft); } /** * Identifies the scrollable parent of the current node element. * * @private * @param {Element[]} nodes - The path of elements to check. * @param {boolean} reverse - Whether to reverse the array to check from bottom to top. * @returns {Element | null} - The first scrollable parent element or null. */ export function getScrollParent(nodes, reverse) { const nodeList = reverse ? [...nodes].reverse() : nodes; for (const node of nodeList) { const computedStyle = window.getComputedStyle(node); const overflowY = computedStyle.overflowY; if ((overflowY === 'auto' || overflowY === 'scroll') && node.scrollHeight > node.clientHeight) { return node; } } const scrollingElement = document.scrollingElement; const docOverflowY = window.getComputedStyle(scrollingElement).overflowY; if (docOverflowY === 'visible') { scrollingElement.style.overflow = 'auto'; return scrollingElement; } return null; }