@humanspeak/svelte-motion 0.3.3 → 0.3.4

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/index.d.ts CHANGED
@@ -5,6 +5,8 @@ export { animate, delay, hover, inView, press, resize, scroll, stagger, transfor
5
5
  export { anticipate, backIn, backInOut, backOut, circIn, circInOut, circOut, cubicBezier, easeIn, easeInOut, easeOut } from 'motion';
6
6
  export { clamp, distance, distance2D, interpolate, mix, pipe, progress, wrap } from 'motion';
7
7
  export type { DragAxis, DragConstraints, DragControls, DragInfo, DragTransition, MotionAnimate, MotionInitial, MotionOnDirectionLock, MotionOnDragTransitionEnd, MotionOnInViewEnd, MotionOnInViewStart, MotionTransition, MotionWhileDrag, MotionWhileFocus, MotionWhileHover, MotionWhileInView, MotionWhileTap, ReducedMotionConfig, Variants } from './types';
8
+ export { useAnimate } from './utils/animate.svelte';
9
+ export type { AnimationScope } from './utils/animate.svelte';
8
10
  export { useAnimationFrame } from './utils/animationFrame';
9
11
  export { useCycle } from './utils/cycle';
10
12
  export type { Cycle, CycleState } from './utils/cycle';
package/dist/index.js CHANGED
@@ -7,6 +7,7 @@ export { animate, delay, hover, inView, press, resize, scroll, stagger, transfor
7
7
  export { anticipate, backIn, backInOut, backOut, circIn, circInOut, circOut, cubicBezier, easeIn, easeInOut, easeOut } from 'motion';
8
8
  // Re-export utility functions
9
9
  export { clamp, distance, distance2D, interpolate, mix, pipe, progress, wrap } from 'motion';
10
+ export { useAnimate } from './utils/animate.svelte';
10
11
  export { useAnimationFrame } from './utils/animationFrame';
11
12
  export { useCycle } from './utils/cycle';
12
13
  export { createDragControls } from './utils/dragControls';
@@ -0,0 +1,66 @@
1
+ import { createScopedAnimate } from 'motion';
2
+ import type { AnimationPlaybackControlsWithThen } from 'motion-dom';
3
+ /**
4
+ * The scope returned by {@link useAnimate}. Functions as a Svelte 5
5
+ * attachment — pass it as `{@attach scope}` on the parent element so the
6
+ * scoped `animate` function can resolve string selectors against it.
7
+ *
8
+ * Mirrors framer-motion's `AnimationScope`. `current` is hydrated once the
9
+ * attachment runs; `animations` tracks every in-flight animation started
10
+ * through the scoped `animate` so they can be stopped together when the
11
+ * element detaches.
12
+ */
13
+ export type AnimationScope<T extends Element = HTMLElement> = ((node: T) => () => void) & {
14
+ /** The parent element, populated when the attachment fires. `undefined` before mount or after detach. */
15
+ current: T | undefined;
16
+ /** Animations currently scoped to this element. */
17
+ animations: AnimationPlaybackControlsWithThen[];
18
+ };
19
+ /**
20
+ * Imperative animation API mirroring framer-motion's `useAnimate`. Returns a
21
+ * tuple `[scope, animate]`:
22
+ *
23
+ * - `scope` is a Svelte 5 attachment: spread it on the parent element with
24
+ * `{@attach scope}`. Once mounted, `scope.current` is the element and
25
+ * `animate('selector', ...)` resolves selectors against it.
26
+ * - `animate(target, keyframes, transition)` accepts the same overloads as
27
+ * motion's standalone `animate` — strings, elements, motion values, and
28
+ * sequences.
29
+ *
30
+ * When the attached element detaches, every animation started through the
31
+ * scoped `animate` is stopped and `scope.animations` is cleared.
32
+ *
33
+ * `animate` ignores calls before the attachment fires — `scope.current` is
34
+ * still `undefined`, and motion throws when asked to query selectors against
35
+ * a missing root. Trigger animations from user events or `$effect` after
36
+ * mount.
37
+ *
38
+ * @template T The parent element type. Defaults to `HTMLElement`.
39
+ * @returns A `[scope, animate]` tuple.
40
+ * @see https://motion.dev/docs/react-use-animate
41
+ *
42
+ * @example
43
+ * ```svelte
44
+ * <script lang="ts">
45
+ * import { useAnimate } from '@humanspeak/svelte-motion'
46
+ *
47
+ * const [scope, animate] = useAnimate()
48
+ *
49
+ * const run = () =>
50
+ * animate(
51
+ * [
52
+ * ['li', { opacity: 1, x: 0 }, { delay: stagger(0.1) }],
53
+ * ['button', { scale: 1.05 }, { at: '-0.2' }]
54
+ * ]
55
+ * )
56
+ * </script>
57
+ *
58
+ * <ul {@attach scope}>
59
+ * <li>One</li>
60
+ * <li>Two</li>
61
+ * <li>Three</li>
62
+ * </ul>
63
+ * <button onclick={run}>Animate</button>
64
+ * ```
65
+ */
66
+ export declare const useAnimate: <T extends Element = HTMLElement>() => [AnimationScope<T>, ReturnType<typeof createScopedAnimate>];
@@ -0,0 +1,66 @@
1
+ import { createScopedAnimate } from 'motion';
2
+ /**
3
+ * Imperative animation API mirroring framer-motion's `useAnimate`. Returns a
4
+ * tuple `[scope, animate]`:
5
+ *
6
+ * - `scope` is a Svelte 5 attachment: spread it on the parent element with
7
+ * `{@attach scope}`. Once mounted, `scope.current` is the element and
8
+ * `animate('selector', ...)` resolves selectors against it.
9
+ * - `animate(target, keyframes, transition)` accepts the same overloads as
10
+ * motion's standalone `animate` — strings, elements, motion values, and
11
+ * sequences.
12
+ *
13
+ * When the attached element detaches, every animation started through the
14
+ * scoped `animate` is stopped and `scope.animations` is cleared.
15
+ *
16
+ * `animate` ignores calls before the attachment fires — `scope.current` is
17
+ * still `undefined`, and motion throws when asked to query selectors against
18
+ * a missing root. Trigger animations from user events or `$effect` after
19
+ * mount.
20
+ *
21
+ * @template T The parent element type. Defaults to `HTMLElement`.
22
+ * @returns A `[scope, animate]` tuple.
23
+ * @see https://motion.dev/docs/react-use-animate
24
+ *
25
+ * @example
26
+ * ```svelte
27
+ * <script lang="ts">
28
+ * import { useAnimate } from '@humanspeak/svelte-motion'
29
+ *
30
+ * const [scope, animate] = useAnimate()
31
+ *
32
+ * const run = () =>
33
+ * animate(
34
+ * [
35
+ * ['li', { opacity: 1, x: 0 }, { delay: stagger(0.1) }],
36
+ * ['button', { scale: 1.05 }, { at: '-0.2' }]
37
+ * ]
38
+ * )
39
+ * </script>
40
+ *
41
+ * <ul {@attach scope}>
42
+ * <li>One</li>
43
+ * <li>Two</li>
44
+ * <li>Three</li>
45
+ * </ul>
46
+ * <button onclick={run}>Animate</button>
47
+ * ```
48
+ */
49
+ export const useAnimate = () => {
50
+ const scope = ((node) => {
51
+ scope.current = node;
52
+ return () => {
53
+ for (const animation of scope.animations) {
54
+ animation.stop();
55
+ }
56
+ scope.animations.length = 0;
57
+ scope.current = undefined;
58
+ };
59
+ });
60
+ scope.current = undefined;
61
+ scope.animations = [];
62
+ const animate = createScopedAnimate({
63
+ scope: scope
64
+ });
65
+ return [scope, animate];
66
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@humanspeak/svelte-motion",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "description": "A Framer Motion-compatible animation library for Svelte 5 that provides smooth, hardware-accelerated animations. Features include spring physics, custom easing, and fluid transitions. Built on top of the motion library, it offers a simple API for creating complex animations with minimal code. Perfect for interactive UIs, micro-interactions, and engaging user experiences.",
5
5
  "keywords": [
6
6
  "svelte",