index.mjs 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. "use client";
  2. import { jsx } from 'react/jsx-runtime';
  3. import { useState, useRef, useEffect } from 'react';
  4. import { LazyContext } from '../../context/LazyContext.mjs';
  5. import { loadFeatures } from '../../motion/features/load-features.mjs';
  6. /**
  7. * Used in conjunction with the `m` component to reduce bundle size.
  8. *
  9. * `m` is a version of the `motion` component that only loads functionality
  10. * critical for the initial render.
  11. *
  12. * `LazyMotion` can then be used to either synchronously or asynchronously
  13. * load animation and gesture support.
  14. *
  15. * ```jsx
  16. * // Synchronous loading
  17. * import { LazyMotion, m, domAnimation } from "framer-motion"
  18. *
  19. * function App() {
  20. * return (
  21. * <LazyMotion features={domAnimation}>
  22. * <m.div animate={{ scale: 2 }} />
  23. * </LazyMotion>
  24. * )
  25. * }
  26. *
  27. * // Asynchronous loading
  28. * import { LazyMotion, m } from "framer-motion"
  29. *
  30. * function App() {
  31. * return (
  32. * <LazyMotion features={() => import('./path/to/domAnimation')}>
  33. * <m.div animate={{ scale: 2 }} />
  34. * </LazyMotion>
  35. * )
  36. * }
  37. * ```
  38. *
  39. * @public
  40. */
  41. function LazyMotion({ children, features, strict = false }) {
  42. const [, setIsLoaded] = useState(!isLazyBundle(features));
  43. const loadedRenderer = useRef(undefined);
  44. /**
  45. * If this is a synchronous load, load features immediately
  46. */
  47. if (!isLazyBundle(features)) {
  48. const { renderer, ...loadedFeatures } = features;
  49. loadedRenderer.current = renderer;
  50. loadFeatures(loadedFeatures);
  51. }
  52. useEffect(() => {
  53. if (isLazyBundle(features)) {
  54. features().then(({ renderer, ...loadedFeatures }) => {
  55. loadFeatures(loadedFeatures);
  56. loadedRenderer.current = renderer;
  57. setIsLoaded(true);
  58. });
  59. }
  60. }, []);
  61. return (jsx(LazyContext.Provider, { value: { renderer: loadedRenderer.current, strict }, children: children }));
  62. }
  63. function isLazyBundle(features) {
  64. return typeof features === "function";
  65. }
  66. export { LazyMotion };