Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: whileHover and whileTap props #1

Open
vbylen opened this issue May 10, 2022 · 16 comments
Open

Feature request: whileHover and whileTap props #1

vbylen opened this issue May 10, 2022 · 16 comments

Comments

@vbylen
Copy link

vbylen commented May 10, 2022

Hi Jay,

Congratulations on hitting it out of the ballpark with legend-motion.

One of my favorite features from framer-motion are the whileTap and whileHover props.

Is this something you would consider adding too?

Thanks!

@jmeistrich
Copy link
Contributor

Thanks @vbylen! Yes, that would great to have, and I think should be fairly easy to add. Would you like to submit a PR to add one or both of those?

whileTap should be very straightforward, but would you expect whileHover to only work in react-native-web?

@jmeistrich
Copy link
Contributor

Actually I changed my mind, I'll add whileTap shortly 😀

@jmeistrich
Copy link
Contributor

Ok done, I added whileTap. It works the same way as Framer Motion, but quick docs with example here: https://legendapp.com/dev/motion/overview/#tap

I'll leave the issue open for adding whileHover at some point.

@vbylen
Copy link
Author

vbylen commented May 11, 2022

That was exceptionally quick 💯

In regards to the whileHover prop, it appears that we'll need to wrap Pressable with a Hoverable provider in order to add the onHoverIn and onHoverOut props.

Luckily for us the one and only @nandorojo has figured out all off this stuff already.

So we could go based off these files from moti:

hoverable.tsx
hoverable-context.tsx
hoverable.native.tsx

And then incorporating them in Pressable like so may do the trick:

pressable.tsx

From there it should be just a simple matter of following the same procedure that was used to add the whileTap commit!

Does this sound good to you?

@jmeistrich
Copy link
Contributor

@vbylen Added in 1.3.1.

I looked at those solutions and did some experimenting, and it seems like it's as easy as adding onMouseEnter/onMouseLeave to the Pressable. I tested with nesting and it seems to work just fine. Do you see any scenarios where it's not working right?

@nandorojo
Copy link

nandorojo commented May 13, 2022

there are cases where opening a modal or clicking something doesn’t fire onMouseLeave. That’s why moti also sets hover to false when you click a different element

@jmeistrich
Copy link
Contributor

Gotcha, ok. Thanks @nandorojo. I'll test for that and try to fix it.

@panjiesw
Copy link

Hi there @jmeistrich, just discovered this library and looks like a great stuff!

I immediately look for how to do interaction with this, and amazingly already covered with whileTap and whileHover. But since I'm looking to animate buttons, I'll also need to pass other props like onPress and accessibility stuffs. Is there any idea on how to do this? Looking at the code, seems like there is no other props passed to the wrapped Pressable currently, other than what's needed for animation

@jmeistrich
Copy link
Contributor

Good point! I will look into passing the Pressable props through.

@minuitagency
Copy link

Hi guys, I'm not sure I understand how to use this prop in a react native component with a touchable ? Thanks, Théo

@panjiesw
Copy link

panjiesw commented May 26, 2022

@jmeistrich yes I also thought that, since interactions in react-native have their specific components. I looked at moti and it also has separate interactions package with MotiPressable. I think separating them in legend-motion will also open up other possible interactions and customization in the future.

Motion.Pressable is a good idea!

@jmeistrich
Copy link
Contributor

@panjiesw After some experimenting I think requiring using a separate Motion.Pressable to get the benefits of whileHover and whileTap would be a big shame so I'm trying to find a better solution. I also found that making an Animated Pressable with Animated.createAnimatedComponent(Pressable) had some problems so we may not be able to animate the Pressable component directly.

I'm experimenting now with adding a prop named pressableProps which would pass those props into the Pressable wrapper. What would you think of that? Are there downsides to that solution I haven't though of?

@nandorojo
Copy link

I don’t recommend trying to hack interactables into every component. RN just wasn’t built that way like the Web.

MotiPressable uses a container element to trap interactions, and the child animates based on the hover/press states. This prevents transform animations from affecting the element itself:

https://twitter.com/fernandotherojo/status/1523493591988928513?s=21&t=BZSO0ix-oOoov6xFCG7vZg

I find the container component to be a necessary piece of interaction animations. However, it’s untenable for a View to have a wrapper everywhere. That’s why I recommend splitting the Pressable into its own component.

@panjiesw
Copy link

@jmeistrich that could work too I think. @nandorojo comment above also shed light to me regarding interactables, might worth a consideration

@jmeistrich
Copy link
Contributor

Yes you're right @nandorojo. I've been doing mostly web development recently so I was thinking too much like web.

In version 2.0.0 I added a Motion.Pressable. whileTap and whileHover now require a Motion.Pressable ancestor, which is uses for tracking whether it is hovered or pressed. You can use it like this:

<Motion.Pressable>
    <Motion.View
        whileHover={{ scale: 1.2 }}
        whileTap={{ y: 20 }}
    />
</Motion.Pressable>

@jmeistrich
Copy link
Contributor

Just a little update: I am leaving this open until this is fixed:

there are cases where opening a modal or clicking something doesn’t fire onMouseLeave. That’s why moti also sets hover to false when you click a different element

I have not had a chance to investigate and find a broken case in action yet. If this is bothering anyone and you can help provide a repo that reproduces that bug I will fix it. Or a PR with a fix works too :).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants