motiondivision / motion

A modern animation library for React and JavaScript
https://motion.dev
MIT License
25.39k stars 839 forks source link

[FEATURE] Ability to pass attributes/props to exiting element in `AnimatePresence` #2517

Closed benface closed 2 months ago

benface commented 9 months ago

Is your feature request related to a problem? Please describe. The documentation for AnimatePresence actually touches on the problem I'm having: "When a component is removed, there's no longer a chance to update its props". But the solution (the custom prop) doesn't apply to my use case. I want the exiting element to have the inert HTML attribute so it is not clickable nor focusable while it disappears.

Describe the solution you'd like I don't know what is technically possible, but react-transition-group has a childFactory prop that allows me to achieve exactly what I want:

<TransitionGroup
  childFactory={(child) => {
    // Make the exiting element inert (not clickable or focusable)
    if (!child.props.in) {
      return cloneElement(child, { inert: '' })
    }
    return child
  }}
>

Describe alternatives you've considered Using react-transition-group, but I would very much prefer to use Motion. 😬

Thank you!

benface commented 2 months ago

Turns out this is possible after all, with usePresence / useIsPresent:

function Component {
  return (
    <AnimatePresence>
      <AnimatePresenceContent key="...">
        <motion.div>...</motion.div>
      </AnimatePresenceContent>
    </AnimatePresence>
  )
}
function AnimatePresenceContent(props: ComponentPropsWithoutRef<'div'>) {
  const isPresent = useIsPresent()
  return (
    <div
      inert={(!isPresent ? '' : undefined) as boolean | undefined} /* ugly hack needed until React 19 */
      {...props}
    />
  )
}

Not sure how I missed it the first time, but it's a lovely API. Closing this issue!