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

Measurement Anchor Mode for <transition-group> #3131

Closed
eli-crow opened this issue Jan 30, 2021 · 9 comments
Closed

Measurement Anchor Mode for <transition-group> #3131

eli-crow opened this issue Jan 30, 2021 · 9 comments

Comments

@eli-crow
Copy link

eli-crow commented Jan 30, 2021

What problem does this feature solve?

Currently, <transition-group>s measure the position of the element from the top left of its bounding box. This works well for purely left-to-right and top-to-bottom situations. However, in some cases, children may change in ways that suggest they are anchored at the bottom or right of their bounding box. This can cause the element to appear to unintuitively jerk up before transitioning again to the correct position.

One example (my use case) is a chat-style application where an item within the chat message list has a part that is hidden after a certain amount of time. In my case, scrolling in the list starts from the bottom. I want the older messages in the list to transition downward to close the now vacant space without causing the changed element to jerk up first. Currently I see no easy workaround to enable me to use transition-group without this jerking. I may have to re-implement the FLIP animation myself, which feels bad.

Another use case is right-to-left text modes.

Currently, in the source code, left and top properties of ClientRect are hard coded. Adding an option to instead measure the delta from the right and bottom of the rect would be a simple change that would enable me use transition-group for my use case.

Codesandbox showing actual and desired behavior: https://codesandbox.io/s/transition-group-bottom-anchored-example-nv3bh?file=/src/App.vue

What does the proposed API look like?

Add an anchor prop, where the options are:

anchor = "top" | "top-right" | "right" | "bottom-right" | "bottom" | "bottom-left" | "left" | "top-left" where each implies measuring from that corner or midpoint.

Or, more simply:

anchor = "start" | "end" where "start" means "measure from the top left" and "end" means "measure from the bottom right"

Example:

<transition-group tag="ul" name="transition-name" anchor="end" class="list">
    <li class="list-item" v-for="item in items" :key="item.key">{{ item.text }}</li>
</transition-group>

In this example, .list-items appear to have a "downward gravity," so when a .list-item changes in height, the items above it will move down, but the .list-item's bottom edge will not have moved.

@eli-crow
Copy link
Author

For the moment, I'm working around the problem by "cloning-and-owning" the source code for TransitionGroup. Simply changing top to bottom; and left to right does exactly what I needed it to do.

@posva
Copy link
Member

posva commented Jan 31, 2021

do you have a boiled down repro to illustrate the bug? Are you changing the origin of the translation after the element is added?

@eli-crow
Copy link
Author

eli-crow commented Jan 31, 2021

This has to do with the reference point on the measured ClientRect used to calculate the translation delta between the start and end states of the F.L.I.P. animation. Measuring from the top-left is not appropriate for lists whose "gravity" tends to the right or downward, such as in chat applications or horizontal lists in rtl languages.

The problem is subtle, but when you notice it, it's quite annoying.

I created this codesandbox to show the actual and desired behavior: https://codesandbox.io/s/transition-group-bottom-anchored-example-nv3bh?file=/src/App.vue

@posva
Copy link
Member

posva commented Feb 1, 2021

Oh, so you are changing the size of an element inside of the transition-group and you want it to stay where it was independently of what changed inside?

Thanks for the clear reproduction with the actual desired behavior 🙌

I'm not sure if this should and could work out of the box, otherwise, the idea of adding a new prop seems alright, it should probably go through an RFC for naming and edge cases

@HcySunYang
Copy link
Member

@posva Should we need to close this one and put it in the RFC for discussion?

@posva
Copy link
Member

posva commented Feb 2, 2021

I think this one is worth having open because it really shows a case that can be improved and how to implement it, but that's my just opinion.

@eli-crow do you feel like opening an RFC at https://github.com/vuejs/rfcs? You seem to have a lot of content already, the idea would be to be more problem-centric to make sure the proposed api can solve all the edge cases as well

@eli-crow
Copy link
Author

eli-crow commented Feb 2, 2021

@posva Exactly. But defining "stay where it was" is dependent on which direction gravity is pointing.

I'll see if I have some time to submit an RFC this week.

@eli-crow
Copy link
Author

eli-crow commented Feb 4, 2021

Submitted my first RFC here: vuejs/rfcs#262
Feel free to close this issue.

@HcySunYang
Copy link
Member

@eli-crow Great thanks, then I close this one.

@github-actions github-actions bot locked and limited conversation to collaborators Oct 26, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants