Source: Dispatcher.js

  1. /**
  2. * This module expose Dispatcher component.
  3. * @module react-cmf/lib/Dispatcher
  4. * @see module:react-cmf/lib/action
  5. */
  6. import PropTypes from 'prop-types';
  7. import { useContext, Children, cloneElement } from 'react';
  8. import cmfConnect from './cmfConnect';
  9. import action from './action';
  10. import actionCreator from './actionCreator';
  11. import { RegistryContext } from './RegistryProvider';
  12. /**
  13. * This component purpose is to decorate any component and map an user event
  14. * to an action to be dispatched
  15. * @example
  16. function myfunc(event, props, context) {
  17. }
  18. <Dispatcher onClick={myfunc}>
  19. <ChildrenElement />
  20. </Dispatcher>
  21. */
  22. export function Dispatcher(props) {
  23. const registry = useContext(RegistryContext);
  24. // console.log('@@@ registry', registry);
  25. /**
  26. * on any even just try to find a onTHEEVENT props.
  27. * If found execute it with the common stuff
  28. * (event, props, context)
  29. * @param {object} event the react event dispatched event
  30. * @param {string} eventName the name of the event
  31. */
  32. function onEvent(event, eventName) {
  33. if (props.stopPropagation) {
  34. event.stopPropagation();
  35. }
  36. if (props.preventDefault) {
  37. event.preventDefault();
  38. }
  39. if (props[eventName]) {
  40. props.dispatchActionCreator(props[eventName], event, props);
  41. }
  42. }
  43. function checkIfActionInfoExist() {
  44. action.getOnProps(props).forEach(name => {
  45. if (typeof props[name] === 'string') {
  46. actionCreator.get({ registry }, props[name]);
  47. }
  48. });
  49. }
  50. checkIfActionInfoExist();
  51. const onProps = action.getOnProps(props);
  52. const childrenWithProps = Children.map(props.children, child => {
  53. const newProps = {};
  54. onProps.forEach(name => {
  55. newProps[name] = event => onEvent(event, name);
  56. });
  57. return cloneElement(child, newProps);
  58. });
  59. return Children.only(childrenWithProps[0]);
  60. }
  61. Dispatcher.propTypes = {
  62. children: PropTypes.node.isRequired,
  63. stopPropagation: PropTypes.bool,
  64. preventDefault: PropTypes.bool,
  65. dispatchActionCreator: PropTypes.func,
  66. };
  67. Dispatcher.displayName = 'Dispatcher';
  68. Dispatcher.defaultProps = {
  69. stopPropagation: false,
  70. preventDefault: false,
  71. };
  72. const ConnectedDispatcher = cmfConnect({
  73. withDispatchActionCreator: true,
  74. })(Dispatcher);
  75. /**
  76. * This component purpose is to decorate any component and map an user event
  77. * to an action to be dispatched
  78. * @example
  79. <Dispatcher onClick="actionCreator:identifier" onDrag="actionCreator:anotherid">
  80. <ChildrenElement />
  81. </Dispatcher>
  82. */
  83. export default ConnectedDispatcher;