UNPKG

@platform/react

Version:

React refs and helpers.

100 lines (99 loc) 3.38 kB
import { Subject } from 'rxjs'; import { share } from 'rxjs/operators'; const EVENT_TYPES = ['CLICK', 'DOUBLE_CLICK', 'UP', 'DOWN', 'ENTER', 'LEAVE']; const dummy = () => null; export const fromProps = (props, args = {}) => { const { getEnabled } = args; const force = args.force === true ? EVENT_TYPES : Array.isArray(args.force) ? args.force : []; const prep = (type, handler) => { return handler ? handler : force.includes(type) ? dummy : undefined; }; return handlers(props.onMouse, { getEnabled, onClick: prep('CLICK', props.onClick), onDoubleClick: prep('DOUBLE_CLICK', props.onDoubleClick), onMouseDown: prep('DOWN', props.onMouseDown), onMouseUp: prep('UP', props.onMouseUp), onMouseEnter: prep('ENTER', props.onMouseEnter), onMouseLeave: prep('LEAVE', props.onMouseLeave), }); }; export const handlers = (handler, args = {}) => { const { getEnabled } = args; const isActive = Boolean(handler) || Object.keys(args).some((key) => typeof args[key] === 'function'); const getSingleHandler = (type) => { switch (type) { case 'CLICK': return args.onClick; case 'DOUBLE_CLICK': return args.onDoubleClick; case 'DOWN': return args.onMouseDown; case 'UP': return args.onMouseUp; case 'ENTER': return args.onMouseEnter; case 'LEAVE': return args.onMouseLeave; default: throw new Error(`Mouse event type '${type}' not supported.`); } }; const next$ = new Subject(); const fireNext = (e) => { next$.next(e); const singular = getSingleHandler(e.type); if (singular) { singular(e._react); } }; const get = (args) => { const hasSingularEvent = Boolean(getSingleHandler(args.type)); const handlers = handler || hasSingularEvent ? [fireNext, handler] : []; return handler || hasSingularEvent ? handle(Object.assign(Object.assign({}, args), { getEnabled, handlers })) : undefined; }; return { isActive, events$: next$.pipe(share()), events: { onClick: get({ type: 'CLICK' }), onDoubleClick: get({ type: 'DOUBLE_CLICK' }), onMouseDown: get({ type: 'DOWN' }), onMouseUp: get({ type: 'UP' }), onMouseEnter: get({ type: 'ENTER' }), onMouseLeave: get({ type: 'LEAVE' }), }, }; }; export const handle = (args) => { const { type, getEnabled } = args; const handlers = (args.handlers || []).filter((e) => Boolean(e)); if (handlers.length === 0) { return undefined; } return (e) => { if (getEnabled && !getEnabled()) { return; } handlers.forEach((handler) => { const args = { type, button: toButton(e), cancel: () => { e.preventDefault(); e.stopPropagation(); }, _react: e, }; handler(args); }); }; }; const toButton = (e) => { switch (e.button) { case 2: return 'RIGHT'; default: return 'LEFT'; } };