Spec RegistrySpec Registry

Help your agents use open-source better. Learn more.

Find usage specs for your project’s dependencies

>

npm-svelte

Describes: npmnpm/svelte

Description
Revolutionary JavaScript framework and compiler that builds web applications without runtime overhead by compiling components at build time.
Author
tessl
Last updated

How to use

npx @tessl/cli registry install tessl/npm-svelte@4.2.0

list-animations.md docs/

1
# List Animations
2
3
FLIP animations for smooth list reordering and element positioning transitions using the First, Last, Invert, Play technique.
4
5
## Capabilities
6
7
### FLIP Animation
8
9
Create smooth transitions when elements change position in lists, providing natural motion for reordering, filtering, and layout changes.
10
11
```javascript { .api }
12
/**
13
* Creates FLIP (First, Last, Invert, Play) animation for element position changes
14
* @param node - DOM element to animate
15
* @param positions - Start and end DOMRect positions
16
* @param params - Animation parameters
17
* @returns Animation configuration
18
*/
19
function flip(
20
node: Element,
21
{ from, to }: { from: DOMRect; to: DOMRect },
22
params?: FlipParams
23
): AnimationConfig;
24
25
interface FlipParams {
26
/** Delay before animation starts (ms) */
27
delay?: number;
28
/** Animation duration (ms) or function based on distance */
29
duration?: number | ((len: number) => number);
30
/** Easing function */
31
easing?: (t: number) => number;
32
}
33
34
interface AnimationConfig {
35
delay?: number;
36
duration?: number;
37
easing?: (t: number) => number;
38
css?: (t: number, u: number) => string;
39
tick?: (t: number, u: number) => void;
40
}
41
```
42
43
**Usage Examples:**
44
45
```javascript
46
// Basic list with FLIP animations
47
import { flip } from "svelte/animate";
48
import { cubicOut } from "svelte/easing";
49
50
let items = [
51
{ id: 1, name: "First item" },
52
{ id: 2, name: "Second item" },
53
{ id: 3, name: "Third item" }
54
];
55
56
function shuffle() {
57
items = items.sort(() => Math.random() - 0.5);
58
}
59
60
// In template:
61
{#each items as item (item.id)}
62
<div animate:flip={{ duration: 300 }}>
63
{item.name}
64
</div>
65
{/each}
66
67
// With custom parameters
68
{#each items as item (item.id)}
69
<div animate:flip={{
70
duration: d => Math.sqrt(d * 200),
71
easing: cubicOut
72
}}>
73
{item.name}
74
</div>
75
{/each}
76
```
77
78
### Dynamic Duration
79
80
Adjust animation duration based on the distance elements need to travel for more natural motion.
81
82
**Usage Examples:**
83
84
```javascript
85
import { flip } from "svelte/animate";
86
87
// Duration proportional to distance
88
{#each todos as todo (todo.id)}
89
<div animate:flip={{ duration: d => Math.sqrt(d * 150) }}>
90
<input type="checkbox" bind:checked={todo.done} />
91
{todo.text}
92
</div>
93
{/each}
94
95
// Fixed duration for consistent timing
96
{#each items as item (item.id)}
97
<div animate:flip={{ duration: 250 }}>
98
{item.content}
99
</div>
100
{/each}
101
```
102
103
### Advanced List Patterns
104
105
Common patterns for using FLIP animations in interactive lists.
106
107
**Sortable List:**
108
109
```javascript
110
import { flip } from "svelte/animate";
111
import { dndzone } from "svelte-dnd-action";
112
113
let items = [
114
{ id: 1, name: "Task 1" },
115
{ id: 2, name: "Task 2" },
116
{ id: 3, name: "Task 3" }
117
];
118
119
function handleDndConsider(e) {
120
items = e.detail.items;
121
}
122
123
function handleDndFinalize(e) {
124
items = e.detail.items;
125
}
126
127
// Template with drag-and-drop and FLIP
128
<div
129
use:dndzone={{ items }}
130
on:consider={handleDndConsider}
131
on:finalize={handleDndFinalize}
132
>
133
{#each items as item (item.id)}
134
<div animate:flip={{ duration: 300 }}>
135
{item.name}
136
</div>
137
{/each}
138
</div>
139
```
140
141
**Filtered List with Animations:**
142
143
```javascript
144
import { flip } from "svelte/animate";
145
import { scale } from "svelte/transition";
146
147
let items = [...]; // Your data
148
let filter = "";
149
150
$: filteredItems = items.filter(item =>
151
item.name.toLowerCase().includes(filter.toLowerCase())
152
);
153
154
// Template
155
<input bind:value={filter} placeholder="Filter items..." />
156
157
{#each filteredItems as item (item.id)}
158
<div
159
in:scale={{ duration: 200 }}
160
out:scale={{ duration: 200 }}
161
animate:flip={{ duration: 300 }}
162
>
163
{item.name}
164
</div>
165
{/each}
166
```
167
168
**Todo List with Categories:**
169
170
```javascript
171
import { flip } from "svelte/animate";
172
import { fly } from "svelte/transition";
173
174
let todos = [...];
175
176
function toggleDone(id) {
177
todos = todos.map(todo =>
178
todo.id === id ? { ...todo, done: !todo.done } : todo
179
);
180
}
181
182
// Template
183
<div class="todo-sections">
184
<section class="pending">
185
<h2>Pending</h2>
186
{#each todos.filter(t => !t.done) as todo (todo.id)}
187
<div
188
animate:flip={{ duration: 300 }}
189
in:fly={{ x: -100 }}
190
out:fly={{ x: 100 }}
191
>
192
<input
193
type="checkbox"
194
checked={todo.done}
195
on:change={() => toggleDone(todo.id)}
196
/>
197
{todo.text}
198
</div>
199
{/each}
200
</section>
201
202
<section class="completed">
203
<h2>Completed</h2>
204
{#each todos.filter(t => t.done) as todo (todo.id)}
205
<div
206
animate:flip={{ duration: 300 }}
207
in:fly={{ x: -100 }}
208
out:fly={{ x: 100 }}
209
>
210
<input
211
type="checkbox"
212
checked={todo.done}
213
on:change={() => toggleDone(todo.id)}
214
/>
215
<s>{todo.text}</s>
216
</div>
217
{/each}
218
</section>
219
</div>
220
```
221
222
### Performance Optimization
223
224
Tips for optimal FLIP animation performance:
225
226
```javascript
227
import { flip } from "svelte/animate";
228
229
// Use shorter durations for better performance
230
{#each items as item (item.id)}
231
<div animate:flip={{ duration: 200 }}>
232
{item.name}
233
</div>
234
{/each}
235
236
// Avoid complex easing functions for large lists
237
import { linear, cubicOut } from "svelte/easing";
238
239
{#each items as item (item.id)}
240
<div animate:flip={{
241
duration: 150,
242
easing: items.length > 50 ? linear : cubicOut
243
}}>
244
{item.name}
245
</div>
246
{/each}
247
248
// Consider disabling animations for very large lists
249
{#each items as item (item.id)}
250
<div animate:flip={{
251
duration: items.length > 100 ? 0 : 300
252
}}>
253
{item.name}
254
</div>
255
{/each}
256
```
257
258
### Integration with Transitions
259
260
Combine FLIP animations with enter/exit transitions for complete motion design:
261
262
```javascript
263
import { flip } from "svelte/animate";
264
import { fade, fly, scale } from "svelte/transition";
265
266
// Fade in/out with position animations
267
{#each items as item (item.id)}
268
<div
269
in:fade={{ duration: 200 }}
270
out:fade={{ duration: 200 }}
271
animate:flip={{ duration: 300 }}
272
>
273
{item.name}
274
</div>
275
{/each}
276
277
// Slide in from side with repositioning
278
{#each items as item (item.id)}
279
<div
280
in:fly={{ x: -50, duration: 200 }}
281
out:fly={{ x: 50, duration: 200 }}
282
animate:flip={{ duration: 300 }}
283
>
284
{item.name}
285
</div>
286
{/each}
287
288
// Scale with smooth repositioning
289
{#each items as item (item.id)}
290
<div
291
in:scale={{ start: 0.8, duration: 150 }}
292
out:scale={{ start: 0.8, duration: 150 }}
293
animate:flip={{ duration: d => Math.sqrt(d * 100) }}
294
>
295
{item.name}
296
</div>
297
{/each}
298
```
299
300
## FLIP Technique Explained
301
302
FLIP stands for:
303
- **First**: Measure the initial position of elements
304
- **Last**: Measure the final position after DOM changes
305
- **Invert**: Apply a transform to move elements back to their starting positions
306
- **Play**: Animate the transform back to 0, creating smooth motion
307
308
This technique allows for smooth animations even when the actual DOM changes happen instantly, making it perfect for list reordering, filtering, and layout changes.