woocommerce/plugins/woocommerce-blocks/assets/js/base/utils/legacy-events.ts

112 lines
2.7 KiB
TypeScript

/**
* External dependencies
*/
import type { AddToCartEventDetail } from '@woocommerce/types';
import type { CoreCollectionNames } from '@woocommerce/blocks/product-collection/types';
const CustomEvent = window.CustomEvent || null;
interface DispatchedEventProperties {
// Whether the event bubbles.
bubbles?: boolean;
// Whether the event is cancelable.
cancelable?: boolean;
// See https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail
detail?: unknown;
// Element that dispatches the event. By default, the body.
element?: Element | null;
}
/**
* Wrapper function to dispatch an event.
*/
export const dispatchEvent = (
name: string,
{
bubbles = false,
cancelable = false,
element,
detail = {},
}: DispatchedEventProperties
): void => {
if ( ! CustomEvent ) {
return;
}
if ( ! element ) {
element = document.body;
}
const event = new CustomEvent( name, {
bubbles,
cancelable,
detail,
} );
element.dispatchEvent( event );
};
export const triggerAddingToCartEvent = (): void => {
dispatchEvent( 'wc-blocks_adding_to_cart', {
bubbles: true,
cancelable: true,
} );
};
export const triggerAddedToCartEvent = ( {
preserveCartData = false,
}: AddToCartEventDetail ): void => {
dispatchEvent( 'wc-blocks_added_to_cart', {
bubbles: true,
cancelable: true,
detail: { preserveCartData },
} );
};
export const triggerProductListRenderedEvent = ( payload: {
collection?: CoreCollectionNames | string;
} ) => {
dispatchEvent( 'wc-blocks_product_list_rendered', {
bubbles: true,
cancelable: true,
detail: payload,
} );
};
export const triggerViewedProductEvent = ( payload: {
collection?: CoreCollectionNames | string;
productId: number;
} ): void => {
dispatchEvent( 'wc-blocks_viewed_product', {
bubbles: true,
cancelable: true,
detail: payload,
} );
};
/**
* Function that listens to a jQuery event and dispatches a native JS event.
* Useful to convert WC Core events into events that can be read by blocks.
*
* Returns a function to remove the jQuery event handler. Ideally it should be
* used when the component is unmounted.
*/
export const translateJQueryEventToNative = (
// Name of the jQuery event to listen to.
jQueryEventName: string,
// Name of the native event to dispatch.
nativeEventName: string,
// Whether the event bubbles.
bubbles = false,
// Whether the event is cancelable.
cancelable = false
): ( () => void ) => {
if ( typeof jQuery !== 'function' ) {
return () => void null;
}
const eventDispatcher = () => {
dispatchEvent( nativeEventName, { bubbles, cancelable } );
};
jQuery( document ).on( jQueryEventName, eventDispatcher );
return () => jQuery( document ).off( jQueryEventName, eventDispatcher );
};