UNPKG

@trellixio/roaster-coffee

Version:
57 lines (56 loc) 2.38 kB
import { useIsomorphicEffect } from '../useIsomorphicEffect'; /** * Dispatches a custom event with the given type and detail. * * @typeParam T - The type of the detail property. * @param type - The type of the custom event. * @param detail - The optional detail property of the custom event. */ function dispatchEvent(type, detail) { window.dispatchEvent(new CustomEvent(type, { detail })); } /** * Creates a custom React hook and event creator function for managing external events with a specified prefix. * * @typeParam Handlers - A record containing event handlers keyed by event type. * @param prefix - The prefix for the event types. * @returns A tuple containing the custom hook `useExternalEvents` and the event creator function `createEvent`. * * @example * ```typescript * const [useExternalEvents, createExternalEvent] = createUseExternalEvents<MyEventHandlers>('myPrefix'); * ``` */ export function createUseExternalEvents(prefix) { /** * A custom React hook that listens to external events with the specified prefix and calls the corresponding handlers. * * @param events - The event handlers to be called when an external event with the specified prefix is dispatched. */ function useExternalEvents(events) { const handlers = Object.keys(events).reduce((acc, eventKey) => { acc[`${prefix}:${eventKey}`] = (event) => events[eventKey](event.detail); return acc; }, {}); useIsomorphicEffect(() => { Object.keys(handlers).forEach((eventKey) => { window.removeEventListener(eventKey, handlers[eventKey]); window.addEventListener(eventKey, handlers[eventKey]); }); return () => Object.keys(handlers).forEach((eventKey) => { window.removeEventListener(eventKey, handlers[eventKey]); }); }, [handlers]); } /** * Creates a function that dispatches an event with the specified prefix and event type. * * @typeParam EventKey - A key of the Handlers type. * @param event - The event type. * @returns A function that takes the payload and dispatches the event. */ function createEvent(event) { return (...payload) => dispatchEvent(`${prefix}:${String(event)}`, payload[0]); } return [useExternalEvents, createEvent]; }