dom_drag-horizontal.js

import trigger from '../events/trigger';

/**
 * @module dragHorizontal
 * @description Make the passed element draggable if it overflows left to right. Fires `gform-utils/horizontal-drag-started`
 * on document when started, and `gform-utils/horizontal-drag-ended` when drag completes.
 *
 * @since 1.0.0
 *
 * @requires trigger
 *
 * @param {HTMLElement} element The element to make draggable.
 *
 * @return {void}
 *
 * @example
 * import { dragHorizontal, getNodes } from  "@gravityforms/utils";
 *
 * const initializeDraggable = () => {
 * 	el.containers.forEach( ( exampleParent ) => {
 * 		const target = getNodes(
 * 			'.example',
 * 			false,
 * 			exampleParent,
 * 			true
 * 		)[ 0 ];
 * 		dragHorizontal( target );
 * 	} );
 * };
 *
 */
export default function dragHorizontal( element ) {
	const state = {
		isDown: false,
		moveEventTriggered: false,
		startX: 0,
		scrollLeft: 0,
	};

	element.addEventListener( 'mousedown', ( e ) => {
		state.isDown = true;
		element.classList.add( 'drag-horizontal--active' );
		state.startX = e.pageX - element.offsetLeft;
		state.scrollLeft = element.scrollLeft;
	} );
	element.addEventListener( 'mouseleave', () => {
		state.isDown = false;
		element.classList.remove( 'drag-horizontal--active' );
	} );
	element.addEventListener( 'mouseup', () => {
		state.isDown = false;
		element.classList.remove( 'drag-horizontal--active' );

		trigger( {
			event: 'gform-utils/horizontal-drag-ended',
			native: false,
		} );
		state.moveEventTriggered = false;
	} );
	element.addEventListener( 'mousemove', ( e ) => {
		if ( ! state.isDown ) {
			return;
		}
		e.preventDefault();
		const x = e.pageX - element.offsetLeft;
		const walk = ( x - state.startX ) * 3;

		element.scrollLeft = state.scrollLeft - walk;

		if ( ! state.moveEventTriggered ) {
			trigger( {
				event: 'gform-utils/horizontal-drag-started',
				native: false,
			} );
			state.moveEventTriggered = true;
		}
	} );
}