@razorpay/blade
Version:
The Design System that powers Razorpay
61 lines (56 loc) • 2.61 kB
JavaScript
import { createAction, createListenerMiddleware } from '../../../@reduxjs/toolkit/dist/redux-toolkit.modern.js';
import { selectActiveTooltipCoordinate, selectActiveTooltipDataKey, selectActiveTooltipIndex, selectActiveLabel, selectIsTooltipActive } from './selectors/tooltipSelectors.js';
var externalEventAction = createAction('externalEvent');
var externalEventsMiddleware = createListenerMiddleware();
/*
* We need a Map keyed by event type because this middleware handles MULTIPLE different event types
* (click, mouseenter, mouseleave, mousedown, mouseup, contextmenu, dblclick, touchstart, touchmove, touchend)
* from the same DOM element. Different event types should NOT cancel each other's animation frames.
* For example, a click event and a mousemove event can happen in quick succession and both should be processed.
* This is different from mouseMoveMiddleware which only handles one event type and uses a single rafId.
*/
var rafIdMap = new Map();
externalEventsMiddleware.startListening({
actionCreator: externalEventAction,
effect: (action, listenerApi) => {
var {
handler,
reactEvent
} = action.payload;
if (handler == null) {
return;
}
reactEvent.persist();
var eventType = reactEvent.type;
// Cancel any pending animation frame for this event type
var existingRafId = rafIdMap.get(eventType);
if (existingRafId !== undefined) {
cancelAnimationFrame(existingRafId);
}
var rafId = requestAnimationFrame(() => {
try {
/*
* Here it is important that we get the latest state inside the animation frame callback,
* not from the outer scope, because there may have been other actions dispatched
* between the time the event was fired and the animation frame callback is executed.
* One of those actions is the one that actually sets the active tooltip state!
*/
var state = listenerApi.getState();
var nextState = {
activeCoordinate: selectActiveTooltipCoordinate(state),
activeDataKey: selectActiveTooltipDataKey(state),
activeIndex: selectActiveTooltipIndex(state),
activeLabel: selectActiveLabel(state),
activeTooltipIndex: selectActiveTooltipIndex(state),
isTooltipActive: selectIsTooltipActive(state)
};
handler(nextState, reactEvent);
} finally {
rafIdMap.delete(eventType);
}
});
rafIdMap.set(eventType, rafId);
}
});
export { externalEventAction, externalEventsMiddleware };
//# sourceMappingURL=externalEventsMiddleware.js.map