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

[feat]: UseSprings for Object #2268

Open
grifdail opened this issue Apr 1, 2024 · 1 comment
Open

[feat]: UseSprings for Object #2268

grifdail opened this issue Apr 1, 2024 · 1 comment
Labels
template: request is a request someone has submitted

Comments

@grifdail
Copy link

grifdail commented Apr 1, 2024

A clear and concise description of what the feature is

an API, similar to useSpring but taking an object ({[key:string]: any }) instead of an number and that return a map of SpringValue. Those spring value are uniquely associated to the key. If a new one is added to the object, a new SpringValue is created, if a key is removed, the associated SpringValue is also deleted.

Why should this feature be included?

Currently, useSprings accept a number and will recreate spring when that count change. This means every spring is bound to an index.
This proposal would allow for spring to be bound to a key. This would means, that when an item is deleted, it's associated spring is also deleted.
In the current system, if we pair each spring to the correspoding index, we get bug like this:

  const nodes = Object.values(tree.nodes);
  const [nodePositionSpring, nodePositionSpringApi] = useSprings(
    nodes.length,
    (index) => {
      return {
        to: { xy: [nodes[index].positionX, nodes[index].positionY] },
      };
    },
    [nodes]
  );

Animation (13)

The most recent elements get the spring value of the elements that just got deleted.

Why not useSpring inside the item itself ?

In the above example, you can see the Green Edge linking the two nodes. These edge are dependent of the position of the two node, therefore they need to be aware of the position of two nodes. They also have to be updated as the nodes moves so we need the spring value.

edges.map((edge) => {
          return <Edge start={nodePositionSpring[edge[0]]} end={nodePositionSpring[edge[1]]}} />;
        })

We could, in theorie use refs to get the value for the nodes themself but that's just moving the problems.

Why not useTransition?

useTransition return a function which we cannot use to animate the Edge at the same time as the Nodes, but i agree that, in theory, it would be great if there was a way to access the springValue themselves.

Please provide an example for how this would work

There's many possibles for for the api.

// function useSprings(map: {[key:string]: ConfigObject)): [{[key:string]: SpringValue}, SpringRef]
const [springs, api] = useSprings({key: {to: {opacity: 0}}); 
// function useSprings(keys: string[]: config: (key: string) => ConfigObject)): [{[key:string]: SpringValue}, SpringRef]
const [springs, api] = useSprings(nodes, key => ({to: nodes[key].opacity)); 
@grifdail grifdail added the template: request is a request someone has submitted label Apr 1, 2024
@myznikovgleb
Copy link

I would like to upvote the feature request. Provided API seems to be handy enough

Is there any progress in achieving the feature?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
template: request is a request someone has submitted
Projects
None yet
Development

No branches or pull requests

2 participants