getMotionObjFromProps.ts 2.1 KB

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