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

$derived springs? #14242

Closed
Acccent opened this issue Nov 10, 2024 · 2 comments
Closed

$derived springs? #14242

Acccent opened this issue Nov 10, 2024 · 2 comments

Comments

@Acccent
Copy link

Acccent commented Nov 10, 2024

Describe the problem

With runes, making one value change depending on another one is super simple with $derived:

let value = $state('a');
let valueDerived = $derived(value == 'a' ? 0 : 1);

However, with svelte/motion still in pre-runes land, if you want that derived value to change smoothly over time, you end up having to do lots of this:

let value = $state('a');
const springDerived = spring(0);

$effect(() => {
  $springDerived = value == 'a' ? 0 : 1;
});

...which is fine, but obviously not ideal. And I'd really love to be able to use runes consistently.

Describe the proposed solution

It'd be great to have a new version of svelte/motion's springs that work exactly like the derived rune when relevant:

let value = $state('a');

let spring1 = $spring(0);
// no dependency, set spring1 directly

let spring2 = $spring(value == 'a' ? 0 : 1);
// derived spring, changes to value make spring2 go smoothly between 0 and 1

let spring3 = $spring(() => {
  let r = 0;
  for (const c of value) {
    r += c.codePointAt(0);
  }
  return r;
});
// akin to derived.by, changes to value make spring3 go smoothly between 0 and... something

Importance

would make my life easier

@Acccent Acccent changed the title $Derived springs? $derived springs? Nov 10, 2024
@brunnerh
Copy link
Member

brunnerh commented Nov 10, 2024

Adding new runes for this would be overkill, it also would interfere with autocompletion of more important runes like $state which disqualifies it immediately.

You can easily write your own function that wraps the $effect, e.g.

// export from a .svelte.js file if needed in many locations
export function derivedSpring(initial, valueFunction) {
	const store = spring(initial);
	$effect.pre(() => {
		store.set(valueFunction());
	});

	return store;
}
let value = $state('a');
const valueDerived = derivedSpring(0, () => value == 'a' ? 0 : 1);

Playground

@dummdidumm
Copy link
Member

There will be a class version of springs which you can track at #11519, closing in favor of that

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

3 participants