getMotionObjFromProps.ts 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import { MotionObject } from "./type";
  2. import { cloneDeep, isObject } from 'lodash';
  3. import warning from './warning';
  4. export interface MergeMotionProps {
  5. [x: string]: any;
  6. motion?: any;
  7. willEnter?: () => void;
  8. didEnter?: () => void;
  9. willLeave?: () => void;
  10. didLeave?: () => void;
  11. onStart?: () => void;
  12. onRest?: () => void;
  13. state?: Record<string, any>;
  14. }
  15. /**
  16. * get motion object from props
  17. *
  18. * example:
  19. *
  20. * ```
  21. * props = { didLeave: componentHandler, motion: { didLeave: userHandler } };
  22. * return { didLeave: () => { componentHandler(); userHandler(); }};
  23. * ```
  24. *
  25. * @param { props: Object }
  26. * @returns { motion: Object }
  27. */
  28. export default function getMotionObjFromProps(props: MergeMotionProps) {
  29. if (typeof props !== 'object' || props === null) {
  30. throw new TypeError(`props should be object type, got ${typeof props}`);
  31. }
  32. const MOTION_PROPS = ['willEnter', 'didEnter', 'willLeave', 'didLeave', 'onStart', 'onRest', 'state'];
  33. const { motion: motionProp = {} } = props;
  34. let motion: MotionObject = {};
  35. if (isObject(motionProp)) {
  36. motion = cloneDeep(motionProp);
  37. for (const key of Object.keys(motionProp)) {
  38. const handler = motionProp[key];
  39. if (typeof handler === 'function') {
  40. if (key in props) {
  41. motion[key] = () => {
  42. props[key](); // call handler function of semi build-in components firstly
  43. handler(); // call user given handler function
  44. };
  45. }
  46. } else {
  47. warning(true, `[Semi] duplicate motion key '${key}' from motion prop and props`);
  48. }
  49. }
  50. } else if (typeof motionProp === 'function') {
  51. const motionFnResult = motionProp(props);
  52. motion = isObject(motionFnResult) ? motionFnResult : {};
  53. }
  54. if (isObject(motion)) {
  55. for (const key of MOTION_PROPS) {
  56. if (key in props && !(key in motion)) {
  57. motion[key] = props[key];
  58. }
  59. }
  60. }
  61. return motion;
  62. }