@humanspeak/svelte-motion 0.0.11 → 0.0.13
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/README.md +12 -66
- package/dist/html/_MotionContainer.svelte +123 -55
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/types.d.ts +9 -0
- package/package.json +137 -135
- package/dist/html/_template.template +0 -10
- package/dist/html/_template_void.template +0 -8
package/README.md
CHANGED
|
@@ -14,70 +14,13 @@
|
|
|
14
14
|
|
|
15
15
|
## Why are we here?
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
Motion vibes, Svelte runes. This brings Motion’s declarative animation goodness to Svelte with `motion.<tag>` components, interaction props, and composable config. If you spot a cool React example, drop it in an issue—we’ll port it. 😍
|
|
18
|
+
|
|
19
|
+
Requests welcome: Have a feature/prop/example you want? Please open an issue (ideally include a working Motion/React snippet or example link) and we’ll prioritize it.
|
|
18
20
|
|
|
19
21
|
## Supported Elements
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
- `motion.a`
|
|
24
|
-
- `motion.article`
|
|
25
|
-
- `motion.aside`
|
|
26
|
-
- `motion.blockquote`
|
|
27
|
-
- `motion.button`
|
|
28
|
-
- `motion.code`
|
|
29
|
-
- `motion.dd`
|
|
30
|
-
- `motion.div`
|
|
31
|
-
- `motion.dl`
|
|
32
|
-
- `motion.dt`
|
|
33
|
-
- `motion.fieldset`
|
|
34
|
-
- `motion.figcaption`
|
|
35
|
-
- `motion.figure`
|
|
36
|
-
- `motion.footer`
|
|
37
|
-
- `motion.form`
|
|
38
|
-
- `motion.h1`
|
|
39
|
-
- `motion.h2`
|
|
40
|
-
- `motion.h3`
|
|
41
|
-
- `motion.h4`
|
|
42
|
-
- `motion.h5`
|
|
43
|
-
- `motion.h6`
|
|
44
|
-
- `motion.header`
|
|
45
|
-
- `motion.label`
|
|
46
|
-
- `motion.legend`
|
|
47
|
-
- `motion.li`
|
|
48
|
-
- `motion.main`
|
|
49
|
-
- `motion.nav`
|
|
50
|
-
- `motion.ol`
|
|
51
|
-
- `motion.option`
|
|
52
|
-
- `motion.p`
|
|
53
|
-
- `motion.pre`
|
|
54
|
-
- `motion.section`
|
|
55
|
-
- `motion.select`
|
|
56
|
-
- `motion.span`
|
|
57
|
-
- `motion.table`
|
|
58
|
-
- `motion.tbody`
|
|
59
|
-
- `motion.td`
|
|
60
|
-
- `motion.textarea`
|
|
61
|
-
- `motion.tfoot`
|
|
62
|
-
- `motion.th`
|
|
63
|
-
- `motion.thead`
|
|
64
|
-
- `motion.tr`
|
|
65
|
-
- `motion.ul`
|
|
66
|
-
|
|
67
|
-
### Void Elements
|
|
68
|
-
|
|
69
|
-
- `motion.area`
|
|
70
|
-
- `motion.base`
|
|
71
|
-
- `motion.br`
|
|
72
|
-
- `motion.col`
|
|
73
|
-
- `motion.embed`
|
|
74
|
-
- `motion.hr`
|
|
75
|
-
- `motion.img`
|
|
76
|
-
- `motion.input`
|
|
77
|
-
- `motion.param`
|
|
78
|
-
- `motion.source`
|
|
79
|
-
- `motion.track`
|
|
80
|
-
- `motion.wbr`
|
|
23
|
+
All standard HTML elements are supported as motion components (e.g., `motion.div`, `motion.button`). See the full set in `src/lib/html/`.
|
|
81
24
|
|
|
82
25
|
## Configuration
|
|
83
26
|
|
|
@@ -100,6 +43,7 @@ Some Motion features are not yet implemented:
|
|
|
100
43
|
- `features` configuration
|
|
101
44
|
- Performance optimizations like `transformPagePoint`
|
|
102
45
|
- Advanced transition controls
|
|
46
|
+
- `layout`/`layoutId` (FLIP) — prototype planned
|
|
103
47
|
|
|
104
48
|
We're actively working on adding these features. Check our GitHub issues for progress updates or to contribute.
|
|
105
49
|
|
|
@@ -117,10 +61,12 @@ This package carefully selects its dependencies to provide a robust and maintain
|
|
|
117
61
|
|
|
118
62
|
### Examples
|
|
119
63
|
|
|
120
|
-
| Motion | REPL
|
|
121
|
-
| -------------------------------------------------------------------------------------------------------- |
|
|
122
|
-
| [React - Enter Animation](https://examples.motion.dev/react/enter-animation) | [View Example](https://svelte.dev/playground/7f60c347729f4ea48b1a4590c9dedc02?version=5.20.2)
|
|
123
|
-
|
|
|
64
|
+
| Motion | Demo / Route | REPL |
|
|
65
|
+
| -------------------------------------------------------------------------------------------------------- | --------------------------------- | ---------------------------------------------------------------------------------------------- |
|
|
66
|
+
| [React - Enter Animation](https://examples.motion.dev/react/enter-animation) | `/tests/motion/enter-animation` | [View Example](https://svelte.dev/playground/7f60c347729f4ea48b1a4590c9dedc02?version=5.20.2) |
|
|
67
|
+
| HTML Content (0→100 counter) | `/tests/motion/html-content` | [View Example](https://svelte.dev/playground/31cd72df4a3242b4b4589501a25e774f?version=5.38.10) |
|
|
68
|
+
| [Random - Shiny Button](https://www.youtube.com/watch?v=jcpLprT5F0I) by [@verse\_](https://x.com/verse_) | `/tests/random/shiny-button` | [View Example](https://svelte.dev/playground/96f9e0bf624f4396adaf06c519147450?version=5.38.10) |
|
|
69
|
+
| [Fancy Like Button](https://github.com/DRlFTER/fancyLikeButton) | `/tests/random/fancy-like-button` | [View Example](https://svelte.dev/playground/c34b7e53d41c48b0ab1eaf21ca120c6e?version=5.38.10) |
|
|
124
70
|
|
|
125
71
|
## License
|
|
126
72
|
|
|
@@ -128,4 +74,4 @@ MIT © [Humanspeak, Inc.](LICENSE)
|
|
|
128
74
|
|
|
129
75
|
## Credits
|
|
130
76
|
|
|
131
|
-
Made with
|
|
77
|
+
Made with ❤️ by [Humanspeak](https://humanspeak.com)
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { getMotionConfig } from '../components/motionConfig.context.js'
|
|
3
|
-
import type { MotionProps } from '../types.js'
|
|
4
|
-
import {
|
|
3
|
+
import type { MotionProps, MotionTransition } from '../types.js'
|
|
4
|
+
import { isNotEmpty } from '../utils/objects.js'
|
|
5
5
|
import { sleep } from '../utils/testing.js'
|
|
6
|
-
import { animate
|
|
6
|
+
import { animate } from 'motion'
|
|
7
7
|
import { type Snippet } from 'svelte'
|
|
8
8
|
import type { SvelteHTMLElements } from 'svelte/elements'
|
|
9
9
|
|
|
@@ -19,6 +19,8 @@
|
|
|
19
19
|
initial: initialProp,
|
|
20
20
|
animate: animateProp,
|
|
21
21
|
transition: transitionProp,
|
|
22
|
+
onAnimationStart: onAnimationStartProp,
|
|
23
|
+
onAnimationComplete: onAnimationCompleteProp,
|
|
22
24
|
style: styleProp,
|
|
23
25
|
class: classProp,
|
|
24
26
|
whileTap: whileTapProp,
|
|
@@ -32,75 +34,141 @@
|
|
|
32
34
|
typeof window !== 'undefined' &&
|
|
33
35
|
window.location.search.includes('@humanspeak-svelte-motion-isPlaywright=true')
|
|
34
36
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
37
|
+
// Compute merged transition without mutating props to avoid effect write loops
|
|
38
|
+
let mergedTransition = $derived<MotionTransition>({
|
|
39
|
+
...(motionConfig?.transition ?? {}),
|
|
40
|
+
...(transitionProp ?? {})
|
|
40
41
|
})
|
|
41
42
|
|
|
43
|
+
// Type guards for animate return types
|
|
44
|
+
function isPromiseLike(value: unknown): value is Promise<unknown> {
|
|
45
|
+
return (
|
|
46
|
+
typeof value === 'object' &&
|
|
47
|
+
value !== null &&
|
|
48
|
+
'then' in (value as { then?: unknown }) &&
|
|
49
|
+
typeof (value as { then?: unknown }).then === 'function'
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
type WithFinished = { finished?: Promise<unknown> }
|
|
53
|
+
function hasFinishedPromise(value: unknown): value is WithFinished {
|
|
54
|
+
return (
|
|
55
|
+
typeof value === 'object' &&
|
|
56
|
+
value !== null &&
|
|
57
|
+
'finished' in (value as { finished?: unknown }) &&
|
|
58
|
+
isPromiseLike((value as { finished?: unknown }).finished)
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
|
|
42
62
|
const runAnimation = () => {
|
|
43
63
|
if (!element || !animateProp) return
|
|
44
|
-
const transitionAmimate = {
|
|
45
|
-
|
|
64
|
+
const transitionAmimate: MotionTransition = mergedTransition ?? {}
|
|
65
|
+
// Fire lifecycle callbacks for main animate transitions
|
|
66
|
+
const payload = $state.snapshot(animateProp)
|
|
67
|
+
onAnimationStartProp?.(payload)
|
|
68
|
+
const controls = animate(element, payload, transitionAmimate)
|
|
69
|
+
// controls may be a promise-like or have a finished promise depending on engine
|
|
70
|
+
if (hasFinishedPromise(controls)) {
|
|
71
|
+
controls.finished?.then(() => onAnimationCompleteProp?.(payload)).catch(() => {})
|
|
72
|
+
} else if (isPromiseLike(controls as unknown)) {
|
|
73
|
+
;(controls as unknown as Promise<unknown>)
|
|
74
|
+
.then(() => onAnimationCompleteProp?.(payload))
|
|
75
|
+
.catch(() => {})
|
|
46
76
|
}
|
|
47
|
-
animate(element, animateProp, transitionAmimate)
|
|
48
77
|
}
|
|
49
78
|
|
|
79
|
+
// Merge style for before/after ready so styles carry through post-anim
|
|
80
|
+
// Merge styles directly in markup; keep effect solely for readiness logic
|
|
81
|
+
|
|
82
|
+
// whileTap handling without relying on motion.press (fallback compatible)
|
|
50
83
|
$effect(() => {
|
|
51
|
-
if (element && isLoaded === 'ready')
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
84
|
+
if (!(element && isLoaded === 'ready' && isNotEmpty(whileTapProp))) return
|
|
85
|
+
|
|
86
|
+
const handlePointerDown = () => {
|
|
87
|
+
animate(element!, whileTapProp!)
|
|
88
|
+
}
|
|
89
|
+
const handlePointerUp = () => {
|
|
90
|
+
// Build reset record preferring animateProp values, falling back to initialProp
|
|
91
|
+
if (isNotEmpty(whileTapProp) && (isNotEmpty(initialProp) || isNotEmpty(animateProp))) {
|
|
92
|
+
const initialRecord = (initialProp ?? {}) as Record<string, unknown>
|
|
93
|
+
const animateRecord = (animateProp ?? {}) as Record<string, unknown>
|
|
94
|
+
const whileTapRecord = (whileTapProp ?? {}) as Record<string, unknown>
|
|
95
|
+
|
|
96
|
+
const keys = new Set<string>([
|
|
97
|
+
...Object.keys(initialRecord),
|
|
98
|
+
...Object.keys(animateRecord)
|
|
99
|
+
])
|
|
100
|
+
const overlappingKeys: string[] = []
|
|
101
|
+
for (const k of keys) if (k in whileTapRecord) overlappingKeys.push(k)
|
|
102
|
+
|
|
103
|
+
const resetRecord: Record<string, unknown> = {}
|
|
104
|
+
for (const k of overlappingKeys) {
|
|
105
|
+
resetRecord[k] = Object.prototype.hasOwnProperty.call(animateRecord, k)
|
|
106
|
+
? animateRecord[k]
|
|
107
|
+
: initialRecord[k]
|
|
108
|
+
}
|
|
109
|
+
if (Object.keys(resetRecord).length > 0) {
|
|
110
|
+
animate(
|
|
111
|
+
element!,
|
|
112
|
+
resetRecord as unknown as import('motion').DOMKeyframesDefinition
|
|
113
|
+
)
|
|
114
|
+
}
|
|
65
115
|
}
|
|
66
116
|
}
|
|
117
|
+
|
|
118
|
+
element.addEventListener('pointerdown', handlePointerDown)
|
|
119
|
+
element.addEventListener('pointerup', handlePointerUp)
|
|
120
|
+
element.addEventListener('pointercancel', handlePointerUp)
|
|
121
|
+
|
|
122
|
+
return () => {
|
|
123
|
+
element?.removeEventListener('pointerdown', handlePointerDown)
|
|
124
|
+
element?.removeEventListener('pointerup', handlePointerUp)
|
|
125
|
+
element?.removeEventListener('pointercancel', handlePointerUp)
|
|
126
|
+
}
|
|
67
127
|
})
|
|
68
128
|
|
|
129
|
+
// Re-run animate when animateProp changes while ready
|
|
69
130
|
$effect(() => {
|
|
70
|
-
if (element) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
isLoaded = 'ready'
|
|
83
|
-
runAnimation()
|
|
84
|
-
}, 5)
|
|
85
|
-
} else {
|
|
86
|
-
dataPath = 2
|
|
87
|
-
isLoaded = 'ready'
|
|
88
|
-
runAnimation()
|
|
89
|
-
}
|
|
90
|
-
} else if (isNotEmpty(initialProp)) {
|
|
91
|
-
dataPath = 3
|
|
131
|
+
if (element && isLoaded === 'ready' && isNotEmpty(animateProp)) {
|
|
132
|
+
runAnimation()
|
|
133
|
+
}
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
$effect(() => {
|
|
137
|
+
if (!(element && isLoaded === 'mounting')) return
|
|
138
|
+
if (animateProp) {
|
|
139
|
+
if (isNotEmpty(initialProp)) {
|
|
140
|
+
// Apply initial instantly BEFORE exposing 'initial' state
|
|
141
|
+
animate(element!, initialProp!, { duration: 0 })
|
|
142
|
+
// Mark initial after styles are applied so tests read CSS=0 while state=initial
|
|
92
143
|
isLoaded = 'initial'
|
|
93
|
-
|
|
94
|
-
|
|
144
|
+
dataPath = 1
|
|
145
|
+
// Then promote to ready and run the enter animation
|
|
146
|
+
requestAnimationFrame(async () => {
|
|
95
147
|
if (isPlaywright) {
|
|
96
|
-
await sleep(
|
|
148
|
+
await sleep(10)
|
|
97
149
|
}
|
|
98
150
|
isLoaded = 'ready'
|
|
99
|
-
|
|
151
|
+
runAnimation()
|
|
152
|
+
})
|
|
100
153
|
} else {
|
|
101
|
-
dataPath =
|
|
154
|
+
dataPath = 2
|
|
102
155
|
isLoaded = 'ready'
|
|
156
|
+
runAnimation()
|
|
103
157
|
}
|
|
158
|
+
} else if (isNotEmpty(initialProp)) {
|
|
159
|
+
// Apply initial instantly BEFORE exposing 'initial' state
|
|
160
|
+
animate(element!, initialProp!, { duration: 0 })
|
|
161
|
+
dataPath = 3
|
|
162
|
+
isLoaded = 'initial'
|
|
163
|
+
requestAnimationFrame(async () => {
|
|
164
|
+
if (isPlaywright) {
|
|
165
|
+
await sleep(10)
|
|
166
|
+
}
|
|
167
|
+
isLoaded = 'ready'
|
|
168
|
+
})
|
|
169
|
+
} else {
|
|
170
|
+
dataPath = 4
|
|
171
|
+
isLoaded = 'ready'
|
|
104
172
|
}
|
|
105
173
|
})
|
|
106
174
|
</script>
|
|
@@ -109,11 +177,11 @@
|
|
|
109
177
|
this={tag}
|
|
110
178
|
bind:this={element}
|
|
111
179
|
{...rest}
|
|
112
|
-
data-playwright={isPlaywright}
|
|
180
|
+
data-playwright={isPlaywright ? isPlaywright : undefined}
|
|
113
181
|
data-is-loaded={isPlaywright ? isLoaded : undefined}
|
|
114
182
|
data-path={isPlaywright ? dataPath : undefined}
|
|
115
|
-
style={
|
|
116
|
-
class={
|
|
183
|
+
style={styleProp}
|
|
184
|
+
class={classProp}
|
|
117
185
|
>
|
|
118
186
|
{#if isLoaded === 'ready'}
|
|
119
187
|
{@render children?.()}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import MotionConfig from './components/MotionConfig.svelte';
|
|
2
2
|
import type { MotionComponents } from './html/index.js';
|
|
3
3
|
export declare const motion: MotionComponents;
|
|
4
|
+
export { animate } from 'motion';
|
|
4
5
|
export type { MotionAnimate, MotionInitial, MotionTransition, MotionWhileTap } from './types.js';
|
|
5
6
|
export { MotionConfig };
|
package/dist/index.js
CHANGED
|
@@ -2,4 +2,6 @@ import MotionConfig from './components/MotionConfig.svelte';
|
|
|
2
2
|
import * as html from './html/index.js';
|
|
3
3
|
// Create the motion object with all components
|
|
4
4
|
export const motion = Object.fromEntries(Object.entries(html).map(([key, component]) => [key.toLowerCase(), component]));
|
|
5
|
+
// Export all types
|
|
6
|
+
export { animate } from 'motion';
|
|
5
7
|
export { MotionConfig };
|
package/dist/types.d.ts
CHANGED
|
@@ -41,6 +41,11 @@ export type MotionTransition = AnimationOptions | undefined;
|
|
|
41
41
|
* ```
|
|
42
42
|
*/
|
|
43
43
|
export type MotionWhileTap = DOMKeyframesDefinition | undefined;
|
|
44
|
+
/**
|
|
45
|
+
* Animation lifecycle callbacks for motion components.
|
|
46
|
+
*/
|
|
47
|
+
export type MotionAnimationStart = ((definition: DOMKeyframesDefinition | undefined) => void) | undefined;
|
|
48
|
+
export type MotionAnimationComplete = ((definition: DOMKeyframesDefinition | undefined) => void) | undefined;
|
|
44
49
|
/**
|
|
45
50
|
* Base motion props shared by all motion components.
|
|
46
51
|
*/
|
|
@@ -53,6 +58,10 @@ export type MotionProps = {
|
|
|
53
58
|
transition?: MotionTransition;
|
|
54
59
|
/** Tap/click interaction animation */
|
|
55
60
|
whileTap?: MotionWhileTap;
|
|
61
|
+
/** Called right before a main animate transition starts */
|
|
62
|
+
onAnimationStart?: MotionAnimationStart;
|
|
63
|
+
/** Called after a main animate transition completes */
|
|
64
|
+
onAnimationComplete?: MotionAnimationComplete;
|
|
56
65
|
/** Inline styles */
|
|
57
66
|
style?: string;
|
|
58
67
|
/** CSS classes */
|
package/package.json
CHANGED
|
@@ -1,136 +1,138 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
"
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
"
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
"
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
"
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
"
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
"
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
2
|
+
"name": "@humanspeak/svelte-motion",
|
|
3
|
+
"version": "0.0.13",
|
|
4
|
+
"description": "A lightweight 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
|
+
"keywords": [
|
|
6
|
+
"svelte",
|
|
7
|
+
"animation",
|
|
8
|
+
"motion",
|
|
9
|
+
"transitions",
|
|
10
|
+
"spring-physics",
|
|
11
|
+
"ui-animation",
|
|
12
|
+
"svelte5",
|
|
13
|
+
"hardware-accelerated",
|
|
14
|
+
"micro-interactions",
|
|
15
|
+
"performance"
|
|
16
|
+
],
|
|
17
|
+
"bugs": {
|
|
18
|
+
"url": "https://github.com/humanspeak/svelte-motion/issues"
|
|
19
|
+
},
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/humanspeak/svelte-motion.git"
|
|
23
|
+
},
|
|
24
|
+
"funding": {
|
|
25
|
+
"type": "github",
|
|
26
|
+
"url": "https://github.com/sponsors/humanspeak"
|
|
27
|
+
},
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"author": "Humanspeak, Inc.",
|
|
30
|
+
"sideEffects": [
|
|
31
|
+
"**/*.css"
|
|
32
|
+
],
|
|
33
|
+
"type": "module",
|
|
34
|
+
"exports": {
|
|
35
|
+
".": {
|
|
36
|
+
"types": "./dist/index.d.ts",
|
|
37
|
+
"svelte": "./dist/index.js"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"svelte": "./dist/index.js",
|
|
41
|
+
"types": "./dist/index.d.ts",
|
|
42
|
+
"files": [
|
|
43
|
+
"dist",
|
|
44
|
+
"!dist/**/*.test.*",
|
|
45
|
+
"!dist/**/*.spec.*",
|
|
46
|
+
"!dist/lib/html/*.template"
|
|
47
|
+
],
|
|
48
|
+
"overrides": {
|
|
49
|
+
"@sveltejs/kit": {
|
|
50
|
+
"cookie": "^0.7.0"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"motion": "^12.23.13"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@eslint/compat": "^1.3.2",
|
|
58
|
+
"@eslint/js": "^9.35.0",
|
|
59
|
+
"@playwright/test": "^1.55.0",
|
|
60
|
+
"@sveltejs/adapter-auto": "^6.1.0",
|
|
61
|
+
"@sveltejs/kit": "^2.41.0",
|
|
62
|
+
"@sveltejs/package": "^2.5.2",
|
|
63
|
+
"@sveltejs/vite-plugin-svelte": "^6.2.0",
|
|
64
|
+
"@tailwindcss/aspect-ratio": "^0.4.2",
|
|
65
|
+
"@tailwindcss/container-queries": "^0.1.1",
|
|
66
|
+
"@tailwindcss/forms": "^0.5.10",
|
|
67
|
+
"@tailwindcss/postcss": "^4.1.13",
|
|
68
|
+
"@tailwindcss/typography": "^0.5.16",
|
|
69
|
+
"@testing-library/jest-dom": "^6.8.0",
|
|
70
|
+
"@testing-library/svelte": "^5.2.8",
|
|
71
|
+
"@types/node": "^22.13.14",
|
|
72
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
73
|
+
"eslint": "^9.35.0",
|
|
74
|
+
"eslint-config-prettier": "^10.1.8",
|
|
75
|
+
"eslint-plugin-svelte": "^3.12.3",
|
|
76
|
+
"globals": "^16.4.0",
|
|
77
|
+
"husky": "^9.1.7",
|
|
78
|
+
"jsdom": "^27.0.0",
|
|
79
|
+
"prettier": "^3.6.2",
|
|
80
|
+
"prettier-plugin-organize-imports": "^4.2.0",
|
|
81
|
+
"prettier-plugin-svelte": "^3.4.0",
|
|
82
|
+
"prettier-plugin-tailwindcss": "^0.6.14",
|
|
83
|
+
"publint": "^0.3.12",
|
|
84
|
+
"svelte": "^5.38.10",
|
|
85
|
+
"svelte-check": "^4.3.1",
|
|
86
|
+
"tailwind-merge": "^3.3.1",
|
|
87
|
+
"tailwind-variants": "^3.1.1",
|
|
88
|
+
"tailwindcss": "^4.1.13",
|
|
89
|
+
"tailwindcss-animate": "^1.0.7",
|
|
90
|
+
"tsx": "^4.20.5",
|
|
91
|
+
"typescript": "^5.9.2",
|
|
92
|
+
"typescript-eslint": "^8.44.0",
|
|
93
|
+
"vite": "^7.1.5",
|
|
94
|
+
"vite-tsconfig-paths": "^5.1.4",
|
|
95
|
+
"vitest": "^3.2.4"
|
|
96
|
+
},
|
|
97
|
+
"peerDependencies": {
|
|
98
|
+
"svelte": "^5.0.0"
|
|
99
|
+
},
|
|
100
|
+
"volta": {
|
|
101
|
+
"node": "22.19.0"
|
|
102
|
+
},
|
|
103
|
+
"publishConfig": {
|
|
104
|
+
"access": "public"
|
|
105
|
+
},
|
|
106
|
+
"tags": [
|
|
107
|
+
"svelte",
|
|
108
|
+
"animation",
|
|
109
|
+
"motion",
|
|
110
|
+
"transitions",
|
|
111
|
+
"spring-physics",
|
|
112
|
+
"performance",
|
|
113
|
+
"ui-animation",
|
|
114
|
+
"micro-interactions",
|
|
115
|
+
"svelte5"
|
|
116
|
+
],
|
|
117
|
+
"scripts": {
|
|
118
|
+
"build": "vite build && npm run package",
|
|
119
|
+
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
120
|
+
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
|
121
|
+
"dev": "vite dev",
|
|
122
|
+
"format": "prettier --write .",
|
|
123
|
+
"generate": "tsx scripts/generate-html.ts",
|
|
124
|
+
"husky": "husky",
|
|
125
|
+
"lint": "prettier --check . && eslint .",
|
|
126
|
+
"lint:fix": "npm run format && eslint . --fix",
|
|
127
|
+
"package": "svelte-kit sync && svelte-package && publint",
|
|
128
|
+
"preview": "vite preview",
|
|
129
|
+
"test": "vitest run --coverage",
|
|
130
|
+
"test:all": "npm run test && npm run test:e2e",
|
|
131
|
+
"test:e2e": "playwright test",
|
|
132
|
+
"test:e2e:debug": "playwright test --debug",
|
|
133
|
+
"test:e2e:report": "playwright show-report",
|
|
134
|
+
"test:e2e:ui": "playwright test --ui",
|
|
135
|
+
"test:only": "vitest run",
|
|
136
|
+
"test:watch": "vitest"
|
|
137
|
+
}
|
|
138
|
+
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import MotionContainer from './_MotionContainer.svelte'
|
|
3
|
-
import type { HTMLElementProps } from '../types.js'
|
|
4
|
-
|
|
5
|
-
let { children, ...rest }: HTMLElementProps = $props()
|
|
6
|
-
</script>
|
|
7
|
-
|
|
8
|
-
<MotionContainer tag="{{tag}}" {...rest}>
|
|
9
|
-
{@render children?.()}
|
|
10
|
-
</MotionContainer>
|