[feat]: UseSprings for Object
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 29.1k
- Forks
- 1.2k
- PR merge metrics
- No merged PRs in 30d
Description
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]
);
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));
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the existing useSprings and useTransition APIs to understand their current constraints. Define how a keyed object or key list should map to SpringValue instances, including behavior when keys are added or removed. Done means the proposed API preserves spring-to-key associations and supports coordinating node and edge animations.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- frontend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100