@platform/react
Version:
React refs and helpers.
100 lines (99 loc) • 3.38 kB
JavaScript
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';
}
};