dom_viewport.js

/**
 * @module viewport
 * @description A set of tools to determine accurate viewport width and height values cross browser, and
 * also element dimensions visible in the viewport.
 *
 */

/**
 * @function elements
 * @description Exports document element and window element normalized across browsers. Needed
 * for correct viewport dimension calculation.
 *
 * @since 1.0.0
 *
 * @return {object} The elements as `{ docElem, win }`.
 *
 * @example
 * import { viewport } from "@gravityforms/utils";
 *
 * function Example() {
 *   const { docElem, win } = viewport.elements();
 *   console.log( docElem.clientHeight );
 * }
 *
 */
export const elements = () => {
	const win = typeof window !== 'undefined' && window;
	const doc = typeof document !== 'undefined' && document;
	const docElem = doc && doc.documentElement;
	return { docElem, win };
};

/**
 * @function width
 * @description Returns the viewport width in pixels.
 *
 * @since 1.0.0
 *
 * @return {number} The viewport width in pixels.
 *
 * @example
 * import { viewport } from "@gravityforms/utils";
 *
 * function Example() {
 *   console.log( viewport.width() );
 * }
 *
 */
export const width = () => {
	const { docElem, win } = elements();
	const a = docElem.clientWidth;
	const b = win.innerWidth;
	return a < b ? b : a;
};

/**
 * @function height
 * @description Returns the viewport height in pixels.
 *
 * @since 1.0.0
 *
 * @return {number} The viewport height in pixels.
 *
 * @example
 * import { viewport } from "@gravityforms/utils";
 *
 * function Example() {
 *   console.log( viewport.height() );
 * }
 *
 */
export const height = () => {
	const { docElem, win } = elements();
	const a = docElem.clientHeight;
	const b = win.innerHeight;
	return a < b ? b : a;
};

/**
 * @function elVisibleHeight
 * @description Returns the height of the visible area of an element in the viewport.
 *
 * @since 1.0.0
 *
 * @param {HTMLElement} el The element to get the visible height of.
 *
 * @return {number} The visible element height in pixels.
 *
 * @example
 * import { getNodes, viewport } from "@gravityforms/utils";
 *
 * function Example() {
 *   const target = getNodes( 'example' )[ 0 ];
 *   console.log( viewport.elVisibleHeight( target ) );
 * }
 *
 */
export const elVisibleHeight = ( el ) => {
	const elHeight = el.offsetHeight;
	const viewportHeight = height();
	const { bottom, top } = el.getBoundingClientRect();
	return Math.max( 0, top > 0 ? Math.min( elHeight, viewportHeight - top ) : Math.min( bottom, viewportHeight ) );
};