Advertisement
Guest User

Untitled

a guest
Oct 15th, 2019
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.17 KB | None | 0 0
  1. import { cloneElement, useMemo } from 'react';
  2. import classNames from 'classnames';
  3.  
  4. interface CloneElementProps {
  5. element: any | null;
  6. children?: any;
  7. }
  8.  
  9. /**
  10. * CloneElement is a wrapper component for createElement function.
  11. * This allows you to describe your cloning element declaratively
  12. * which is a more natural API for React.
  13. */
  14. export function CloneElement<T = any>({ element, children, ...rest }: CloneElementProps & Partial<T>) {
  15. const getProjectedProps = useMemo(() => props => {
  16. const childProps = element.props;
  17.  
  18. return Object.keys(props).reduce((acc, key) => {
  19. const prop = props[key];
  20. const childProp = childProps[key];
  21.  
  22. if (typeof prop === 'function' && typeof childProp === 'function') {
  23. acc[key] = args => {
  24. prop(args);
  25. childProp(args);
  26. };
  27. } else if (key === 'className') {
  28. acc[key] = classNames(prop, childProp);
  29. } else {
  30. acc[key] = prop;
  31. }
  32.  
  33. return acc;
  34. }, {});
  35. }, [rest]);
  36.  
  37. if (element === null) {
  38. return children;
  39. }
  40.  
  41. const newProps = getProjectedProps(rest);
  42. return cloneElement(element, {
  43. ...element.props,
  44. ...newProps,
  45. children
  46. });
  47. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement