coily 0.13.1 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/vue.d.ts CHANGED
@@ -1,57 +1,267 @@
1
- import { _ as SpringOptions, a as ConfigShape, c as Shape, f as Spring, g as SpringConfig, l as SpringObject, n as SpringSystemOptions, o as PartialShape, p as SpringPosition, s as ReadonlyShape, t as SpringSystem } from "./system-86fsXJN_.js";
1
+ import { C as SpringDefinitionOptions, S as SpringDefinition, c as ConfigShape, d as ReadonlyShape, f as Shape, i as SpringSystemOptions, l as PartialShape, m as Spring, n as SpringOptions, o as CompositeSpring, p as Purpose, r as SpringSystem, t as CompositeSpringOptions, y as SpringSource } from "./system-Ci-R4RaI.js";
2
2
  import { App, MaybeRefOrGetter, Ref, SlotsType } from "vue";
3
3
  //#region src/vue/reactive-spring.d.ts
4
- type UseSpringOptions = MaybeRefOrGetter<SpringOptions | SpringConfig | undefined>;
5
- interface ReactiveSpringRef<V, W = V> extends Ref<V, W> {
4
+ /**
5
+ * Config for a scalar `useSpring`: a `SpringDefinition`, any option shape
6
+ * `defineSpring` accepts, or a ref/getter of either. Reactive config
7
+ * reconfigures the spring in place when it changes; `undefined` means the
8
+ * default config.
9
+ */
10
+ type UseSpringConfig = MaybeRefOrGetter<SpringDefinitionOptions | SpringDefinition | undefined>;
11
+ /**
12
+ * The reactive surface `useSpring` returns: a writable ref of the
13
+ * animated value with the rest of the spring attached. Reads track
14
+ * reactively and update once per tick while the spring moves.
15
+ *
16
+ * Writing the main ref displaces the spring — it springs back toward its
17
+ * target. To move the spring, drive the target you passed to
18
+ * `useSpring`.
19
+ *
20
+ * The ref is also a `SpringSource`: it goes anywhere a source does —
21
+ * another `useSpring`, a `mapSpring` leaf, a composite channel target.
22
+ * Followers read the backing spring through `SpringSourceSymbol`, never
23
+ * through the ref's tracked getter, so following registers no Vue
24
+ * dependencies — an effect that touches a follower's leader stays
25
+ * independent of the leader's animation.
26
+ */
27
+ interface ReactiveSpringRef<V, W = V> extends Ref<V, W>, SpringSource<V> {
28
+ /**
29
+ * The current velocity in value units per second, as a writable ref.
30
+ * Writing flings the spring; it settles back to its target.
31
+ */
6
32
  readonly velocity: Ref<V, W>;
33
+ /**
34
+ * Estimated milliseconds until the spring rests, as a reactive ref: 0
35
+ * while resting. Writes are ignored.
36
+ */
7
37
  readonly timeRemaining: Ref<number>;
38
+ /** Whether the spring is resting, as a reactive ref. Writes are ignored. */
8
39
  readonly isResting: Ref<boolean>;
40
+ /**
41
+ * A promise that resolves when the spring next comes to rest — already
42
+ * resolved while resting. Retargeting mid-flight extends the wait;
43
+ * disposal resolves it.
44
+ */
9
45
  readonly settled: Promise<void>;
46
+ /** Snaps the spring to `value` with no animation, target included. */
10
47
  readonly jumpTo: (value: W) => void;
11
48
  }
12
49
  //#endregion
13
- //#region src/vue/spring-object.d.ts
14
- type UseSpringObjectOptions<T extends object> = MaybeRefOrGetter<ConfigShape<T> | undefined>;
15
- interface SpringObjectRef<T extends object> extends ReactiveSpringRef<ReadonlyShape<T>, PartialShape<T>> {}
50
+ //#region src/vue/composite-spring.d.ts
51
+ /**
52
+ * Config for an object `useSpring`: a `ConfigShape` — one `SpringDefinition`
53
+ * for every channel, `null`, or a shape with configs at any level — or a
54
+ * ref/getter of one. Reactive config reconfigures channels in place.
55
+ *
56
+ * Unlike scalar config, positions here take `SpringDefinition` instances
57
+ * only (build them with `defineSpring`): a plain object is always read as
58
+ * a per-channel shape.
59
+ */
60
+ type UseCompositeSpringConfig<T extends object> = MaybeRefOrGetter<ConfigShape<T> | undefined>;
61
+ /**
62
+ * The reactive handle for a composite spring: a ref reading the
63
+ * deep-readonly composite value and accepting partial shapes on writes,
64
+ * with `velocity`, `timeRemaining`, and `isResting` refs plus `settled`
65
+ * and `jumpTo` attached. Writing the main ref displaces the named
66
+ * channels; drive the `useSpring` target to move them.
67
+ */
68
+ interface CompositeSpringRef<T extends object> extends ReactiveSpringRef<ReadonlyShape<T>, PartialShape<T>> {}
16
69
  //#endregion
17
70
  //#region src/vue/spring.d.ts
71
+ /**
72
+ * The reactive handle for a scalar spring: a writable ref of the
73
+ * animated number, with `velocity`, `timeRemaining`, and `isResting`
74
+ * refs plus `settled` and `jumpTo` attached. Writing the main ref
75
+ * displaces the spring; drive the `useSpring` target to move it.
76
+ */
18
77
  interface SpringRef extends ReactiveSpringRef<number> {}
19
- declare function useSpring(target: MaybeRefOrGetter<number>, options?: UseSpringOptions): SpringRef;
20
- declare function useSpring(target: SpringRef, options?: UseSpringOptions): SpringRef;
21
- declare function useSpring<T extends object>(target: SpringObjectRef<T>, options?: UseSpringObjectOptions<T>): SpringObjectRef<T>;
22
- declare function useSpring<T extends object>(target: T & Shape<T>, options?: UseSpringObjectOptions<T>): SpringObjectRef<T>;
23
- declare function useSpring<T extends object>(target: Ref<T & Shape<T>>, options?: UseSpringObjectOptions<T>): SpringObjectRef<T>;
24
- declare function useSpring<T extends object>(target: () => T & Shape<T>, options?: UseSpringObjectOptions<T>): SpringObjectRef<T>;
78
+ /**
79
+ * Creates a scalar spring and returns it as a `SpringRef`. The target
80
+ * is a number to animate toward, or a `SpringSource` to follow — another
81
+ * `useSpring` ref, a `mapSpring` result, a pooled `Spring` — or a
82
+ * ref/getter of either. Reactive numbers retarget the spring whenever
83
+ * they change, momentum intact; a getter of a source re-follows when its
84
+ * own dependencies change, so `useSpring(() => (split.value ? left :
85
+ * right))` switches leaders live. Reactive `config` reconfigures the
86
+ * spring in place; while following, it configures the follower's own
87
+ * motion — the leader's config plays no part.
88
+ *
89
+ * Following bypasses Vue reactivity — the spring subscribes to the
90
+ * source directly — so effects and getters never gain a dependency on a
91
+ * leader's animation.
92
+ *
93
+ * Call it during `setup()` below a provided spring system (the
94
+ * coily/nuxt module, or `useSpringSystem()` in an ancestor). The spring
95
+ * is disposed with the component's scope, and composables are loop-safe:
96
+ * map over targets for several independent springs.
97
+ *
98
+ * `options.purpose` marks what the spring animates — `'appearance'`
99
+ * (a cross-fade, a color) keeps animating under reduced motion, `'motion'`
100
+ * (the default) snaps. It is read once, so unlike `config` it is not
101
+ * reactive.
102
+ *
103
+ * @example
104
+ * ```ts
105
+ * const target = ref(0)
106
+ * const x = useSpring(target, { duration: 500, bounce: 0.3 })
107
+ * // template: <div :style="{ translate: `${x}px 0` }" @click="target = 300" />
108
+ *
109
+ * const opacity = useSpring(shown ? 1 : 0, undefined, { purpose: 'appearance' })
110
+ * ```
111
+ */
112
+ declare function useSpring(target: MaybeRefOrGetter<number | SpringSource>, config?: UseSpringConfig, options?: SpringOptions): SpringRef;
113
+ /**
114
+ * Creates a composite spring that follows another `useSpring` object ref
115
+ * channel by channel, animating toward the leader's live values.
116
+ *
117
+ * Call it during `setup()` below a provided spring system. The springs
118
+ * are disposed with the component's scope.
119
+ */
120
+ declare function useSpring<T extends object>(target: CompositeSpringRef<T>, config?: UseCompositeSpringConfig<T>, options?: CompositeSpringOptions<T>): CompositeSpringRef<T>;
121
+ /**
122
+ * Creates a composite spring over a numeric shape — a plain object or
123
+ * array whose leaves are all numbers, or a ref/getter of one — and
124
+ * returns a `CompositeSpringRef`: reads are the deep-readonly composite
125
+ * value, writes take partial shapes. The shape is fixed at creation.
126
+ * Reactive targets retarget the channels, momentum intact — a ref on
127
+ * replacement or nested mutation, a getter whenever its reactive
128
+ * dependencies change. Reactive `config` accepts a per-channel config
129
+ * shape.
130
+ *
131
+ * Call it during `setup()` below a provided spring system. The springs
132
+ * are disposed with the component's scope.
133
+ *
134
+ * `options.purpose` marks reduced-motion behavior per channel: a single
135
+ * `Purpose` for all, or a shape mirroring the value. It is read once, so
136
+ * unlike `config` it is not reactive.
137
+ */
138
+ declare function useSpring<T extends object>(target: MaybeRefOrGetter<T & Shape<T>>, config?: UseCompositeSpringConfig<T>, options?: CompositeSpringOptions<T>): CompositeSpringRef<T>;
139
+ /**
140
+ * Creates a composite spring driven by a getter of a numeric shape: the
141
+ * springs retarget whenever the getter's reactive dependencies change.
142
+ * The shape itself is fixed at creation.
143
+ *
144
+ * (This is the getter case of the shape overload above, split out
145
+ * because the shape doesn't infer through `MaybeRefOrGetter`'s
146
+ * function member.)
147
+ *
148
+ * Call it during `setup()` below a provided spring system. The springs
149
+ * are disposed with the component's scope.
150
+ */
151
+ declare function useSpring<T extends object>(target: () => T & Shape<T>, config?: UseCompositeSpringConfig<T>, options?: CompositeSpringOptions<T>): CompositeSpringRef<T>;
25
152
  //#endregion
26
153
  //#region src/vue/pool.d.ts
154
+ /**
155
+ * Imperative spring factories bound to the provided system, for dynamic
156
+ * sets of springs — particles, per-item effects — created and disposed
157
+ * at arbitrary times. Any pooled spring still alive when the creating
158
+ * scope tears down is disposed automatically; disposing one manually
159
+ * before that is fine.
160
+ */
27
161
  interface SpringPool {
28
- createSpring(position: SpringPosition, config?: SpringConfig): Spring;
29
- createSpringObject<T extends object>(value: T & Shape<T>, config?: ConfigShape<T>): SpringObject<T>;
162
+ /**
163
+ * Creates a pooled spring at rest at `value`. Without `config`, the
164
+ * default applies. `options.purpose` sets reduced-motion behavior —
165
+ * `'appearance'` keeps animating, `'motion'` (default) snaps.
166
+ */
167
+ createSpring(value: number, config?: SpringDefinition, options?: SpringOptions): Spring;
168
+ /**
169
+ * Creates a pooled spring already following `source`, starting at its
170
+ * current value. `options.purpose` sets reduced-motion behavior.
171
+ */
172
+ createSpring(source: SpringSource, config?: SpringDefinition, options?: SpringOptions): Spring;
173
+ /**
174
+ * Creates a pooled composite spring over a numeric shape whose leaves
175
+ * are all numbers. `config` applies per channel: one `SpringDefinition`
176
+ * for all, or a shape with configs at any level. `options.purpose` sets
177
+ * reduced-motion behavior per channel the same way.
178
+ */
179
+ createSpring<T extends object>(value: T & Shape<T>, config?: ConfigShape<T>, options?: CompositeSpringOptions<T>): CompositeSpring<T>;
30
180
  }
181
+ /**
182
+ * Returns spring factories bound to the provided spring system, with
183
+ * lifetimes tied to the current effect scope: every pooled spring still
184
+ * alive at scope teardown is disposed, so leaked motions are
185
+ * structurally impossible.
186
+ *
187
+ * Call it during `setup()` — or inside an effect scope — below a
188
+ * provided spring system. Outside a scope, pooled springs are only
189
+ * disposed manually.
190
+ */
31
191
  declare function useSpringPool(): SpringPool;
32
192
  //#endregion
33
193
  //#region src/vue/component.d.ts
34
194
  interface SpringValueProps {
195
+ /** The value to animate toward. Changing it retargets the spring, momentum intact. */
35
196
  target: number;
36
- config?: SpringOptions | SpringConfig;
197
+ /**
198
+ * Spring config: a `SpringDefinition` or any option shape `defineSpring`
199
+ * accepts. Changing it reconfigures the spring in place; omit it for
200
+ * the default.
201
+ */
202
+ config?: SpringDefinitionOptions | SpringDefinition;
203
+ /**
204
+ * What the spring animates — `'motion'` (default) or `'appearance'`.
205
+ * `'appearance'` (a cross-fade, a color) keeps animating under reduced
206
+ * motion. Read once at mount; later changes are ignored.
207
+ * @default 'motion'
208
+ */
209
+ purpose?: Purpose;
37
210
  }
211
+ /** `SpringValue` emits no events. */
38
212
  type SpringValueEmits = Record<string, never>;
213
+ /** What `SpringValue` passes to its default slot. */
39
214
  interface SpringValueSlotScope {
215
+ /** The current animated value. */
40
216
  value: number;
217
+ /** The current velocity, in value units per second. */
41
218
  velocity: number;
219
+ /** Whether the spring is resting. */
42
220
  isResting: boolean;
221
+ /** Estimated milliseconds until the spring rests. */
43
222
  timeRemaining: number;
223
+ /** Snaps the spring to `value` with no animation, target included. */
44
224
  jumpTo: (value: number) => void;
45
225
  }
226
+ /** Slot types: `default` receives the live `SpringValueSlotScope`. */
46
227
  type SpringValueSlots = SlotsType<{
47
228
  default: SpringValueSlotScope;
48
229
  }>;
230
+ /**
231
+ * Renderless component exposing one springed number through its default
232
+ * slot — the template-only sibling of `useSpring`. Must sit below a
233
+ * provided spring system.
234
+ *
235
+ * @example
236
+ * ```vue
237
+ * <SpringValue :target="expanded ? 1 : 0" purpose="appearance" v-slot="{ value }">
238
+ * <div :style="{ opacity: value }" />
239
+ * </SpringValue>
240
+ * ```
241
+ */
49
242
  declare const SpringValue: import("vue").DefineSetupFnComponent<SpringValueProps, SpringValueEmits, SpringValueSlots, SpringValueProps & {
50
243
  [x: `on${Capitalize<string>}`]: ((...args: unknown[]) => any) | undefined;
51
244
  }, import("vue").PublicProps>;
52
245
  //#endregion
53
246
  //#region src/vue/system.d.ts
247
+ /**
248
+ * Supplies a spring system you created and manage yourself — coily never
249
+ * starts or stops it. With `app`, the system is installed app-wide
250
+ * (what the Nuxt module does); without, it is provided to the current
251
+ * component and its descendants, including this component's own
252
+ * `useSpring` calls. Mostly useful in tests.
253
+ */
54
254
  declare function provideSpringSystem(system: SpringSystem, app?: App): void;
255
+ /**
256
+ * Returns the spring system provided by this component or an ancestor,
257
+ * creating one when none exists. A created system is provided to this
258
+ * component and its descendants and started/stopped with the component's
259
+ * mount lifecycle.
260
+ *
261
+ * Idempotent: call it near the root and again in any descendant.
262
+ * `options` only applies when the call actually creates a system.
263
+ * Throws outside `setup()`.
264
+ */
55
265
  declare function useSpringSystem(options?: SpringSystemOptions): SpringSystem;
56
266
  //#endregion
57
- export { type SpringObjectRef, type SpringPool, type SpringRef, SpringValue, type SpringValueProps, type SpringValueSlots, type UseSpringObjectOptions, provideSpringSystem, useSpring, useSpringPool, useSpringSystem };
267
+ export { type CompositeSpringRef, type SpringPool, type SpringRef, SpringValue, type SpringValueProps, type SpringValueSlots, provideSpringSystem, useSpring, useSpringPool, useSpringSystem };
package/dist/vue.js CHANGED
@@ -1,4 +1,4 @@
1
- import { n as SpringConfig, t as createSpringSystem } from "./system-Csho09XW.js";
1
+ import { a as SpringDefinition, n as SpringSourceSymbol, r as isSpringSource, t as createSpringSystem } from "./system-BXxAHM2a.js";
2
2
  import { computed, customRef, defineComponent, getCurrentInstance, getCurrentScope, inject, onBeforeUnmount, onMounted, onScopeDispose, provide, toRefs, toValue, watchSyncEffect } from "vue";
3
3
  //#region src/vue/local.ts
4
4
  const localProvides = /* @__PURE__ */ new WeakMap();
@@ -25,10 +25,27 @@ function injectLocal(key) {
25
25
  //#endregion
26
26
  //#region src/vue/system.ts
27
27
  const SpringSystemKey = Symbol.for("coily/spring-system");
28
+ /**
29
+ * Supplies a spring system you created and manage yourself — coily never
30
+ * starts or stops it. With `app`, the system is installed app-wide
31
+ * (what the Nuxt module does); without, it is provided to the current
32
+ * component and its descendants, including this component's own
33
+ * `useSpring` calls. Mostly useful in tests.
34
+ */
28
35
  function provideSpringSystem(system, app) {
29
36
  if (app) app.provide(SpringSystemKey, system);
30
37
  else provideLocal(SpringSystemKey, system);
31
38
  }
39
+ /**
40
+ * Returns the spring system provided by this component or an ancestor,
41
+ * creating one when none exists. A created system is provided to this
42
+ * component and its descendants and started/stopped with the component's
43
+ * mount lifecycle.
44
+ *
45
+ * Idempotent: call it near the root and again in any descendant.
46
+ * `options` only applies when the call actually creates a system.
47
+ * Throws outside `setup()`.
48
+ */
32
49
  function useSpringSystem(options) {
33
50
  if (!getCurrentInstance()) throw new Error("useSpringSystem must be called inside setup()");
34
51
  const existing = injectLocal(SpringSystemKey);
@@ -47,11 +64,11 @@ function injectSpringSystem() {
47
64
  if (!system) throw new Error("No SpringSystem found — install the coily/nuxt module or call useSpringSystem() in an ancestor component");
48
65
  return system;
49
66
  }
50
- function resolveSpringConfig(options) {
67
+ function resolveSpringConfig(config) {
51
68
  return computed(() => {
52
- const opts = toValue(options);
53
- if (opts instanceof SpringConfig) return opts;
54
- return opts ? new SpringConfig(opts) : void 0;
69
+ const resolved = toValue(config);
70
+ if (resolved instanceof SpringDefinition) return resolved;
71
+ return resolved ? new SpringDefinition(resolved) : void 0;
55
72
  });
56
73
  }
57
74
  function createReactiveSpringRef(spring, config, instanceKey) {
@@ -116,66 +133,78 @@ function createReactiveSpringRef(spring, config, instanceKey) {
116
133
  });
117
134
  Object.defineProperty(ref, "settled", { get: () => spring.settled });
118
135
  Object.defineProperty(ref, instanceKey, { value: spring });
136
+ Object.defineProperty(ref, SpringSourceSymbol, { value: spring[SpringSourceSymbol] });
119
137
  return ref;
120
138
  }
121
139
  //#endregion
122
- //#region src/vue/spring-object.ts
123
- /** @internal */
124
- const SpringObjectInstanceKey = Symbol("spring-object");
125
- function hasSpringObjectInstance(value) {
126
- return typeof value === "object" && value !== null && SpringObjectInstanceKey in value;
140
+ //#region src/vue/composite-spring.ts
141
+ const CompositeSpringInstanceKey = Symbol("composite-spring");
142
+ function hasCompositeSpringInstance(value) {
143
+ return typeof value === "object" && value !== null && CompositeSpringInstanceKey in value;
127
144
  }
128
- function resolveConfigShape(options) {
129
- return computed(() => toValue(options));
145
+ function resolveConfigShape(config) {
146
+ return computed(() => toValue(config));
130
147
  }
131
- function createSpringObjectRef(value, options) {
148
+ function createCompositeSpringRef(value, config, options) {
132
149
  const system = injectSpringSystem();
133
- const config = resolveConfigShape(options);
134
- const spring = system.createSpringObject(toValue(value), config.value);
135
- const ref = createReactiveSpringRef(spring, config, SpringObjectInstanceKey);
150
+ const resolvedConfig = resolveConfigShape(config);
151
+ const spring = system.createSpring(toValue(value), resolvedConfig.value, options);
152
+ const ref = createReactiveSpringRef(spring, resolvedConfig, CompositeSpringInstanceKey);
136
153
  watchSyncEffect(() => {
137
154
  spring.target = toValue(value);
138
155
  });
139
156
  return ref;
140
157
  }
141
- function createLinkedSpringObjectRef(leaderRef, options) {
158
+ function createLinkedCompositeSpringRef(leaderRef, config, options) {
142
159
  const system = injectSpringSystem();
143
- const leader = leaderRef[SpringObjectInstanceKey];
144
- const config = resolveConfigShape(options);
145
- const spring = system.createSpringObject(leader.value, config.value);
160
+ const leader = leaderRef[CompositeSpringInstanceKey];
161
+ const resolvedConfig = resolveConfigShape(config);
162
+ const spring = system.createSpring(leader.value, resolvedConfig.value, options);
146
163
  spring.target = leader;
147
- return createReactiveSpringRef(spring, config, SpringObjectInstanceKey);
164
+ return createReactiveSpringRef(spring, resolvedConfig, CompositeSpringInstanceKey);
148
165
  }
149
166
  //#endregion
150
167
  //#region src/vue/spring.ts
151
- /** @internal */
152
168
  const SpringInstanceKey = Symbol("spring");
153
169
  function hasSpringInstance(value) {
154
170
  return typeof value === "object" && value !== null && SpringInstanceKey in value;
155
171
  }
156
- function useSpring(target, options) {
157
- if (hasSpringInstance(target)) return createLinkedSpringRef(target, options);
158
- if (hasSpringObjectInstance(target)) return createLinkedSpringObjectRef(target, options);
159
- if (typeof toValue(target) === "number") return createSpringRef(target, options);
160
- return createSpringObjectRef(target, options);
172
+ function useSpring(target, config, options) {
173
+ if (hasSpringInstance(target)) return createLinkedSpringRef(target, config, options);
174
+ if (hasCompositeSpringInstance(target)) return createLinkedCompositeSpringRef(target, config, options);
175
+ const resolved = toValue(target);
176
+ if (typeof resolved === "number" || isSpringSource(resolved)) return createSpringRef(target, config, options);
177
+ return createCompositeSpringRef(target, config, options);
161
178
  }
162
- function createSpringRef(target, options) {
179
+ function createSpringRef(target, config, options) {
163
180
  const system = injectSpringSystem();
164
- const config = resolveSpringConfig(options);
165
- const spring = system.createSpring(toValue(target), config.value);
166
- const ref = createReactiveSpringRef(spring, config, SpringInstanceKey);
181
+ const resolvedConfig = resolveSpringConfig(config);
182
+ const initial = toValue(target);
183
+ const spring = system.createSpring(typeof initial === "number" ? initial : initial[SpringSourceSymbol].value, resolvedConfig.value, options);
184
+ const ref = createReactiveSpringRef(spring, resolvedConfig, SpringInstanceKey);
167
185
  watchSyncEffect(() => {
168
186
  spring.target = toValue(target);
169
187
  });
170
188
  return ref;
171
189
  }
172
- function createLinkedSpringRef(leaderRef, options) {
190
+ function createLinkedSpringRef(leaderRef, config, options) {
173
191
  const system = injectSpringSystem();
174
- const config = resolveSpringConfig(options);
175
- return createReactiveSpringRef(system.createSpring({ target: leaderRef[SpringInstanceKey] }, config.value), config, SpringInstanceKey);
192
+ const leader = leaderRef[SpringInstanceKey];
193
+ const resolvedConfig = resolveSpringConfig(config);
194
+ return createReactiveSpringRef(system.createSpring(leader, resolvedConfig.value, options), resolvedConfig, SpringInstanceKey);
176
195
  }
177
196
  //#endregion
178
197
  //#region src/vue/pool.ts
198
+ /**
199
+ * Returns spring factories bound to the provided spring system, with
200
+ * lifetimes tied to the current effect scope: every pooled spring still
201
+ * alive at scope teardown is disposed, so leaked motions are
202
+ * structurally impossible.
203
+ *
204
+ * Call it during `setup()` — or inside an effect scope — below a
205
+ * provided spring system. Outside a scope, pooled springs are only
206
+ * disposed manually.
207
+ */
179
208
  function useSpringPool() {
180
209
  const system = injectSpringSystem();
181
210
  const live = /* @__PURE__ */ new Set();
@@ -189,18 +218,27 @@ function useSpringPool() {
189
218
  onScopeDispose(() => {
190
219
  for (const spring of live) spring.dispose();
191
220
  }, true);
192
- return {
193
- createSpring: (position, config) => adopt(system.createSpring(position, config)),
194
- createSpringObject(value, config) {
195
- return adopt(system.createSpringObject(value, config));
196
- }
197
- };
221
+ const create = system.createSpring.bind(system);
222
+ const createSpring = ((value, config, options) => adopt(create(value, config, options)));
223
+ return { createSpring };
198
224
  }
199
225
  //#endregion
200
226
  //#region src/vue/component.ts
227
+ /**
228
+ * Renderless component exposing one springed number through its default
229
+ * slot — the template-only sibling of `useSpring`. Must sit below a
230
+ * provided spring system.
231
+ *
232
+ * @example
233
+ * ```vue
234
+ * <SpringValue :target="expanded ? 1 : 0" purpose="appearance" v-slot="{ value }">
235
+ * <div :style="{ opacity: value }" />
236
+ * </SpringValue>
237
+ * ```
238
+ */
201
239
  const SpringValue = defineComponent((props, { slots, expose }) => {
202
240
  const { target, config } = toRefs(props);
203
- const spring = useSpring(target, config);
241
+ const spring = useSpring(target, config, { purpose: props.purpose });
204
242
  expose({
205
243
  value: spring,
206
244
  velocity: spring.velocity,
@@ -217,7 +255,11 @@ const SpringValue = defineComponent((props, { slots, expose }) => {
217
255
  }) ?? null;
218
256
  }, {
219
257
  name: "SpringValue",
220
- props: ["target", "config"]
258
+ props: [
259
+ "target",
260
+ "config",
261
+ "purpose"
262
+ ]
221
263
  });
222
264
  //#endregion
223
265
  export { SpringValue, provideSpringSystem, useSpring, useSpringPool, useSpringSystem };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coily",
3
- "version": "0.13.1",
3
+ "version": "0.14.0",
4
4
  "description": "Simulate values using spring physics",
5
5
  "homepage": "https://github.com/tkofh/coily#readme",
6
6
  "bugs": {