All files / src/motion/utils use-visual-element.ts

100% Statements 23/23
100% Branches 30/30
100% Functions 5/5
100% Lines 20/20

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53  33x 33x   33x   33x   33x     33x           1358x 1358x 1358x     1358x         1358x   1358x 671x                 1358x 1358x 674x     1358x 674x     1358x   1358x    
import * as React from "react"
import { MutableRefObject, useContext, useEffect, useRef } from "react"
import { PresenceContext } from "../../context/PresenceContext"
import { MotionProps } from "../../motion/types"
import { useVisualElementContext } from "../../context/MotionContext"
import { CreateVisualElement, VisualElement } from "../../render/types"
import { useIsomorphicLayoutEffect } from "../../utils/use-isomorphic-effect"
import { VisualState } from "./use-visual-state"
import { LazyContext } from "../../context/LazyContext"
import { MotionConfigProps } from "../../components/MotionConfig"
 
export function useVisualElement<Instance, RenderState>(
    Component: string | React.ComponentType,
    visualState: VisualState<Instance, RenderState>,
    props: MotionProps & MotionConfigProps,
    createVisualElement?: CreateVisualElement<Instance>
): VisualElement<Instance> | undefined {
    const lazyContext = useContext(LazyContext)
    const parent = useVisualElementContext()
    const presenceContext = useContext(PresenceContext)
 
    const visualElementRef: MutableRefObject<VisualElement | undefined> =
        useRef(undefined)
 
    /**
     * If we haven't preloaded a renderer, check to see if we have one lazy-loaded
     */
    if (!createVisualElement) createVisualElement = lazyContext.renderer
 
    if (!visualElementRef.current && createVisualElement) {
        visualElementRef.current = createVisualElement(Component, {
            visualState,
            parent,
            props,
            presenceId: presenceContext?.id,
            blockInitialAnimation: presenceContext?.initial === false,
        })
    }
 
    const visualElement = visualElementRef.current
    useIsomorphicLayoutEffect(() => {
        visualElement?.syncRender()
    })
 
    useEffect(() => {
        visualElement?.animationState?.animateChanges()
    })
 
    useIsomorphicLayoutEffect(() => () => visualElement?.notifyUnmount(), [])
 
    return visualElement
}