UNPKG

@wordpress/compose

Version:
102 lines (90 loc) 3.26 kB
/** * WordPress dependencies */ import { Component, forwardRef } from '@wordpress/element'; import deprecated from '@wordpress/deprecated'; /** * Internal dependencies */ import { createHigherOrderComponent } from '../../utils/create-higher-order-component'; import Listener from './listener'; /** * Listener instance responsible for managing document event handling. */ const listener = new Listener(); /** * Higher-order component creator which, given an object of DOM event types and * values corresponding to a callback function name on the component, will * create or update a window event handler to invoke the callback when an event * occurs. On behalf of the consuming developer, the higher-order component * manages unbinding when the component unmounts, and binding at most a single * event handler for the entire application. * * @deprecated * * @param {Record<keyof GlobalEventHandlersEventMap, string>} eventTypesToHandlers Object with keys of DOM * event type, the value a * name of the function on * the original component's * instance which handles * the event. * * @return {any} Higher-order component. */ export default function withGlobalEvents( eventTypesToHandlers ) { deprecated( 'wp.compose.withGlobalEvents', { since: '5.7', alternative: 'useEffect', } ); // @ts-ignore We don't need to fix the type-related issues because this is deprecated. return createHigherOrderComponent( ( WrappedComponent ) => { class Wrapper extends Component { constructor( /** @type {any} */ props ) { super( props ); this.handleEvent = this.handleEvent.bind( this ); this.handleRef = this.handleRef.bind( this ); } componentDidMount() { Object.keys( eventTypesToHandlers ).forEach( ( eventType ) => { listener.add( eventType, this ); } ); } componentWillUnmount() { Object.keys( eventTypesToHandlers ).forEach( ( eventType ) => { listener.remove( eventType, this ); } ); } handleEvent( /** @type {any} */ event ) { const handler = eventTypesToHandlers[ /** @type {keyof GlobalEventHandlersEventMap} */ ( event.type ) ]; if ( typeof this.wrappedRef[ handler ] === 'function' ) { this.wrappedRef[ handler ]( event ); } } handleRef( /** @type {any} */ el ) { this.wrappedRef = el; // Any component using `withGlobalEvents` that is not setting a `ref` // will cause `this.props.forwardedRef` to be `null`, so we need this // check. if ( this.props.forwardedRef ) { this.props.forwardedRef( el ); } } render() { return ( <WrappedComponent { ...this.props.ownProps } ref={ this.handleRef } /> ); } } return forwardRef( ( props, ref ) => { return <Wrapper ownProps={ props } forwardedRef={ ref } />; } ); }, 'withGlobalEvents' ); }