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
A cybernetically enhanced web application framework that compiles to highly optimized JavaScript with reactive state management and component-based architecture.
Author
tessl
Last updated

How to use

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

reactivity-window.md docs/

1
# Window Reactivity
2
3
Svelte provides reactive values for common window properties that automatically update when the browser window changes. These are particularly useful for responsive design and window-based interactions.
4
5
## Capabilities
6
7
### Window Dimensions
8
9
Reactive values for window size properties.
10
11
```typescript { .api }
12
/**
13
* Reactive view of window.innerWidth
14
* @since 5.11.0
15
*/
16
const innerWidth: ReactiveValue<number | undefined>;
17
18
/**
19
* Reactive view of window.innerHeight
20
* @since 5.11.0
21
*/
22
const innerHeight: ReactiveValue<number | undefined>;
23
24
/**
25
* Reactive view of window.outerWidth
26
* @since 5.11.0
27
*/
28
const outerWidth: ReactiveValue<number | undefined>;
29
30
/**
31
* Reactive view of window.outerHeight
32
* @since 5.11.0
33
*/
34
const outerHeight: ReactiveValue<number | undefined>;
35
```
36
37
**Usage Examples:**
38
39
```typescript
40
import { innerWidth, innerHeight, outerWidth, outerHeight } from "svelte/reactivity/window";
41
42
// Responsive breakpoints
43
const isSmallScreen = $derived(innerWidth.current < 768);
44
const isMediumScreen = $derived(innerWidth.current >= 768 && innerWidth.current < 1024);
45
const isLargeScreen = $derived(innerWidth.current >= 1024);
46
47
// Aspect ratio calculations
48
const aspectRatio = $derived(
49
innerWidth.current && innerHeight.current
50
? innerWidth.current / innerHeight.current
51
: 16/9
52
);
53
54
// Window size for canvas or dynamic layouts
55
let canvas;
56
$effect(() => {
57
if (canvas && innerWidth.current && innerHeight.current) {
58
canvas.width = innerWidth.current;
59
canvas.height = innerHeight.current;
60
}
61
});
62
63
// Responsive component behavior
64
const itemsPerRow = $derived(() => {
65
if (!innerWidth.current) return 1;
66
if (innerWidth.current < 600) return 1;
67
if (innerWidth.current < 900) return 2;
68
if (innerWidth.current < 1200) return 3;
69
return 4;
70
});
71
```
72
73
### Window Position
74
75
Reactive values for window position properties.
76
77
```typescript { .api }
78
/**
79
* Reactive view of window.screenLeft (updated in requestAnimationFrame)
80
* @since 5.11.0
81
*/
82
const screenLeft: ReactiveValue<number | undefined>;
83
84
/**
85
* Reactive view of window.screenTop (updated in requestAnimationFrame)
86
* @since 5.11.0
87
*/
88
const screenTop: ReactiveValue<number | undefined>;
89
```
90
91
**Usage Examples:**
92
93
```typescript
94
import { screenLeft, screenTop } from "svelte/reactivity/window";
95
96
// Track window position
97
const windowPosition = $derived({
98
x: screenLeft.current || 0,
99
y: screenTop.current || 0
100
});
101
102
// Multi-monitor awareness
103
$effect(() => {
104
const x = screenLeft.current;
105
const y = screenTop.current;
106
107
if (x !== undefined && y !== undefined) {
108
console.log(`Window moved to (${x}, ${y})`);
109
110
// Adjust behavior based on screen position
111
if (x < 0 || y < 0) {
112
console.log("Window is on a secondary monitor");
113
}
114
}
115
});
116
```
117
118
### Scroll Position
119
120
Reactive values for window scroll position.
121
122
```typescript { .api }
123
/**
124
* Reactive view of window.scrollX
125
* @since 5.11.0
126
*/
127
const scrollX: ReactiveValue<number | undefined>;
128
129
/**
130
* Reactive view of window.scrollY
131
* @since 5.11.0
132
*/
133
const scrollY: ReactiveValue<number | undefined>;
134
```
135
136
**Usage Examples:**
137
138
```typescript
139
import { scrollX, scrollY } from "svelte/reactivity/window";
140
141
// Scroll-based effects
142
const isScrolled = $derived((scrollY.current || 0) > 100);
143
const scrollProgress = $derived(() => {
144
const y = scrollY.current || 0;
145
const maxScroll = document.documentElement.scrollHeight - window.innerHeight;
146
return Math.min(y / maxScroll, 1);
147
});
148
149
// Sticky header behavior
150
let header;
151
$effect(() => {
152
if (header) {
153
header.classList.toggle("scrolled", isScrolled);
154
}
155
});
156
157
// Parallax effects
158
let parallaxElement;
159
$effect(() => {
160
if (parallaxElement && scrollY.current !== undefined) {
161
const offset = scrollY.current * 0.5;
162
parallaxElement.style.transform = `translateY(${offset}px)`;
163
}
164
});
165
166
// Hide/show elements based on scroll direction
167
let lastScrollY = 0;
168
let scrollDirection = $state("up");
169
170
$effect(() => {
171
const currentScrollY = scrollY.current || 0;
172
173
if (currentScrollY > lastScrollY) {
174
scrollDirection = "down";
175
} else if (currentScrollY < lastScrollY) {
176
scrollDirection = "up";
177
}
178
179
lastScrollY = currentScrollY;
180
});
181
```
182
183
### Network Status
184
185
Reactive value for network connectivity.
186
187
```typescript { .api }
188
/**
189
* Reactive view of navigator.onLine
190
* @since 5.11.0
191
*/
192
const online: ReactiveValue<boolean | undefined>;
193
```
194
195
**Usage Examples:**
196
197
```typescript
198
import { online } from "svelte/reactivity/window";
199
200
// Network status indicator
201
const isOnline = $derived(online.current ?? true);
202
const networkStatus = $derived(isOnline ? "online" : "offline");
203
204
// Conditional behavior based on connectivity
205
$effect(() => {
206
if (isOnline) {
207
console.log("Connected - syncing data");
208
syncOfflineData();
209
} else {
210
console.log("Disconnected - switching to offline mode");
211
enableOfflineMode();
212
}
213
});
214
215
// Queue operations when offline
216
let pendingOperations = $state([]);
217
218
function performOperation(operation) {
219
if (isOnline) {
220
executeOperation(operation);
221
} else {
222
pendingOperations = [...pendingOperations, operation];
223
}
224
}
225
226
$effect(() => {
227
if (isOnline && pendingOperations.length > 0) {
228
// Process queued operations when back online
229
pendingOperations.forEach(executeOperation);
230
pendingOperations = [];
231
}
232
});
233
```
234
235
### Device Pixel Ratio
236
237
Reactive value for device pixel ratio (display scaling).
238
239
```typescript { .api }
240
/**
241
* Reactive view of window.devicePixelRatio
242
* Note: Behavior differs between browsers - Chrome responds to zoom, Firefox/Safari don't
243
* @since 5.11.0
244
*/
245
const devicePixelRatio: {
246
get current(): number | undefined;
247
};
248
```
249
250
**Usage Examples:**
251
252
```typescript
253
import { devicePixelRatio } from "svelte/reactivity/window";
254
255
// High DPI canvas rendering
256
let canvas;
257
let ctx;
258
259
$effect(() => {
260
if (canvas && ctx) {
261
const ratio = devicePixelRatio.current || 1;
262
const rect = canvas.getBoundingClientRect();
263
264
// Scale canvas for high DPI displays
265
canvas.width = rect.width * ratio;
266
canvas.height = rect.height * ratio;
267
268
ctx.scale(ratio, ratio);
269
270
// Redraw with high DPI scaling
271
redrawCanvas();
272
}
273
});
274
275
// Image loading based on pixel density
276
const imageSource = $derived(() => {
277
const ratio = devicePixelRatio.current || 1;
278
279
if (ratio >= 3) {
280
return "image@3x.jpg";
281
} else if (ratio >= 2) {
282
return "image@2x.jpg";
283
} else {
284
return "image.jpg";
285
}
286
});
287
288
// CSS-in-JS with device pixel ratio
289
const styles = $derived(() => ({
290
fontSize: `${16 * (devicePixelRatio.current || 1)}px`,
291
borderWidth: `${1 / (devicePixelRatio.current || 1)}px`
292
}));
293
```
294
295
## Server-Side Behavior
296
297
All window reactivity values return `undefined` on the server since window properties are not available during server-side rendering.
298
299
```typescript
300
// Safe server-side usage
301
const isMobile = $derived((innerWidth.current || 1024) < 768);
302
const scrolled = $derived((scrollY.current || 0) > 0);
303
const isOnline = $derived(online.current ?? true); // Default to online
304
```
305
306
## Types
307
308
```typescript { .api }
309
interface ReactiveValue<T> {
310
get current(): T;
311
}
312
```
313
314
## Best Practices
315
316
1. **Handle undefined values**: Always provide fallbacks for server-side rendering
317
2. **Debounce expensive operations**: Window events can fire frequently
318
3. **Use for responsive design**: Perfect for JavaScript-based responsive behavior
319
4. **Combine with CSS**: Use alongside CSS media queries for complete responsive design
320
5. **Consider performance**: Some values update in `requestAnimationFrame` loops
321
6. **Test across browsers**: `devicePixelRatio` behavior varies between browsers
322
323
## Common Patterns
324
325
### Responsive Breakpoints
326
327
```typescript
328
import { innerWidth } from "svelte/reactivity/window";
329
330
const breakpoints = {
331
sm: 640,
332
md: 768,
333
lg: 1024,
334
xl: 1280
335
};
336
337
const screen = $derived(() => {
338
const width = innerWidth.current || 1024;
339
340
if (width >= breakpoints.xl) return "xl";
341
if (width >= breakpoints.lg) return "lg";
342
if (width >= breakpoints.md) return "md";
343
if (width >= breakpoints.sm) return "sm";
344
return "xs";
345
});
346
```
347
348
### Scroll-Based Navigation
349
350
```typescript
351
import { scrollY } from "svelte/reactivity/window";
352
353
let sections = [];
354
let activeSection = $state(0);
355
356
$effect(() => {
357
const currentScroll = scrollY.current || 0;
358
359
// Find active section based on scroll position
360
const active = sections.findIndex((section, index) => {
361
const nextSection = sections[index + 1];
362
const sectionTop = section.offsetTop;
363
const sectionBottom = nextSection ? nextSection.offsetTop : document.body.scrollHeight;
364
365
return currentScroll >= sectionTop - 100 && currentScroll < sectionBottom - 100;
366
});
367
368
if (active !== -1) {
369
activeSection = active;
370
}
371
});
372
```