| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- "use client";
- import { jsxs, jsx } from 'react/jsx-runtime';
- import { warning, invariant } from 'motion-utils';
- import { forwardRef, useContext } from 'react';
- import { LayoutGroupContext } from '../context/LayoutGroupContext.mjs';
- import { LazyContext } from '../context/LazyContext.mjs';
- import { MotionConfigContext } from '../context/MotionConfigContext.mjs';
- import { MotionContext } from '../context/MotionContext/index.mjs';
- import { useCreateMotionContext } from '../context/MotionContext/create.mjs';
- import { isBrowser } from '../utils/is-browser.mjs';
- import { featureDefinitions } from './features/definitions.mjs';
- import { loadFeatures } from './features/load-features.mjs';
- import { motionComponentSymbol } from './utils/symbol.mjs';
- import { useMotionRef } from './utils/use-motion-ref.mjs';
- import { useVisualElement } from './utils/use-visual-element.mjs';
- /**
- * Create a `motion` component.
- *
- * This function accepts a Component argument, which can be either a string (ie "div"
- * for `motion.div`), or an actual React component.
- *
- * Alongside this is a config option which provides a way of rendering the provided
- * component "offline", or outside the React render cycle.
- */
- function createRendererMotionComponent({ preloadedFeatures, createVisualElement, useRender, useVisualState, Component, }) {
- preloadedFeatures && loadFeatures(preloadedFeatures);
- function MotionComponent(props, externalRef) {
- /**
- * If we need to measure the element we load this functionality in a
- * separate class component in order to gain access to getSnapshotBeforeUpdate.
- */
- let MeasureLayout;
- const configAndProps = {
- ...useContext(MotionConfigContext),
- ...props,
- layoutId: useLayoutId(props),
- };
- const { isStatic } = configAndProps;
- const context = useCreateMotionContext(props);
- const visualState = useVisualState(props, isStatic);
- if (!isStatic && isBrowser) {
- useStrictMode(configAndProps, preloadedFeatures);
- const layoutProjection = getProjectionFunctionality(configAndProps);
- MeasureLayout = layoutProjection.MeasureLayout;
- /**
- * Create a VisualElement for this component. A VisualElement provides a common
- * interface to renderer-specific APIs (ie DOM/Three.js etc) as well as
- * providing a way of rendering to these APIs outside of the React render loop
- * for more performant animations and interactions
- */
- context.visualElement = useVisualElement(Component, visualState, configAndProps, createVisualElement, layoutProjection.ProjectionNode);
- }
- /**
- * The mount order and hierarchy is specific to ensure our element ref
- * is hydrated by the time features fire their effects.
- */
- return (jsxs(MotionContext.Provider, { value: context, children: [MeasureLayout && context.visualElement ? (jsx(MeasureLayout, { visualElement: context.visualElement, ...configAndProps })) : null, useRender(Component, props, useMotionRef(visualState, context.visualElement, externalRef), visualState, isStatic, context.visualElement)] }));
- }
- MotionComponent.displayName = `motion.${typeof Component === "string"
- ? Component
- : `create(${Component.displayName ?? Component.name ?? ""})`}`;
- const ForwardRefMotionComponent = forwardRef(MotionComponent);
- ForwardRefMotionComponent[motionComponentSymbol] = Component;
- return ForwardRefMotionComponent;
- }
- function useLayoutId({ layoutId }) {
- const layoutGroupId = useContext(LayoutGroupContext).id;
- return layoutGroupId && layoutId !== undefined
- ? layoutGroupId + "-" + layoutId
- : layoutId;
- }
- function useStrictMode(configAndProps, preloadedFeatures) {
- const isStrict = useContext(LazyContext).strict;
- /**
- * If we're in development mode, check to make sure we're not rendering a motion component
- * as a child of LazyMotion, as this will break the file-size benefits of using it.
- */
- if (process.env.NODE_ENV !== "production" &&
- preloadedFeatures &&
- isStrict) {
- const strictMessage = "You have rendered a `motion` component within a `LazyMotion` component. This will break tree shaking. Import and render a `m` component instead.";
- configAndProps.ignoreStrict
- ? warning(false, strictMessage)
- : invariant(false, strictMessage);
- }
- }
- function getProjectionFunctionality(props) {
- const { drag, layout } = featureDefinitions;
- if (!drag && !layout)
- return {};
- const combined = { ...drag, ...layout };
- return {
- MeasureLayout: drag?.isEnabled(props) || layout?.isEnabled(props)
- ? combined.MeasureLayout
- : undefined,
- ProjectionNode: combined.ProjectionNode,
- };
- }
- export { createRendererMotionComponent };
|