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

Provide a 'reset' utility for function-based Springs #14868

Open
Acccent opened this issue Dec 31, 2024 · 0 comments
Open

Provide a 'reset' utility for function-based Springs #14868

Acccent opened this issue Dec 31, 2024 · 0 comments

Comments

@Acccent
Copy link

Acccent commented Dec 31, 2024

Describe the problem

The new Spring class is great, and in particular the fact that Spring.of() can be used in conjuction with spring.set() is super useful.

However, after using .set(), the spring stays at the provided value until reactivity causes its initial function to be reevaluated. This is expected and not a problem at all, but it's just undesirable in some cases, so I was wondering if DX could be improved a bit.

Consider something like:

// a, b, c and d change rarely
let a = $state(2);
let b = $state(4);
let c = $state(8);
let d = $state(16);

const spring = Spring.of(() => a * b * c * d);

function setSpringValue(x) {
  spring.set(x);
}

The spring will remain at the value passed as x until either a, b, c or d change, which could take a long time (or could happen literally immediately, making the whole thing a bit useless).
If we want the spring to go back to a * b * c * d after reaching x, one way to do it is:

// ...
let calculatedTarget = $derived(a * b * c * d);

const spring = Spring.of(() => calculatedTarget);

function setSpringValue(x) {
  spring.set(x).then(() => spring.set(calculatedTarget);
}

Again, this is fine, but can just turn into a lot of boilerplate in real-world situations with lots of spring-based UIs.

Describe the proposed solution

To go along with the set() feature, it would be nice to have a way to force a reevaluation of the function initially provided to the Spring.

Something like spring.reset() could make things a little cleaner imo, instructing the spring to re-run its initial function without having to create a $derived.

- let calculatedTarget = $derived(a * b * c * d);
- const spring = Spring.of(() => calculatedTarget);

- function setSpringValue(x) {
-   spring.set(x).then(() => spring.set(calculatedTarget);
- }

+ const spring = Spring.of(() => a * b * c * d);

+ function setSpringValue(x) {
+  spring.set(x).then(() => spring.reset();
+ }

And additionally, maybe an option could be passed to .set(), to make this process even easier?

// default behavior:
spring.set(x, { reevaluate: 'reactive' });

// stop responding to reactivity until `x` is reached, then reevaluate the initial fn
spring.set(x, { reevaluate: 'after' });

// responds to reactivity throughout animation towards `x` as usual, and upon reaching `x` reevaluate the initial fn
spring.set(x, { reevaluate: 'reactiveAfter' });

// stops reactivity entirely until manually re-enabled with spring.reset()
spring.set(x, { reevaluate: 'never' });

Conversely, this would also allow for more control in situations where a, b, c and d change a lot, and we just want the spring to chill for a bit.

Importance

would make my life easier

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

No branches or pull requests

2 participants