-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: provide
MediaQuery
/ prefersReducedMotion
closes #5346
- Loading branch information
1 parent
37e6c7f
commit c5c4bea
Showing
5 changed files
with
76 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,10 @@ | ||
import { MediaQuery } from 'svelte/reactivity'; | ||
|
||
export * from './spring.js'; | ||
export * from './tweened.js'; | ||
|
||
/** | ||
* A media query that matches if the user has requested reduced motion. | ||
* @type {MediaQuery} | ||
*/ | ||
export const prefersReducedMotion = new MediaQuery('(prefers-reduced-motion: reduce)'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { get, tick } from '../internal/client/runtime.js'; | ||
import { set, source } from '../internal/client/reactivity/sources.js'; | ||
import { effect_tracking, render_effect } from '../internal/client/reactivity/effects.js'; | ||
|
||
/** | ||
* Creates a media query and provides a `matches` property that reflects its current state. | ||
*/ | ||
export class MediaQuery { | ||
#matches = source(false); | ||
#subscribers = 0; | ||
#query; | ||
/** @type {any} */ | ||
#listener; | ||
|
||
get matches() { | ||
if (effect_tracking()) { | ||
render_effect(() => { | ||
if (this.#subscribers === 0) { | ||
this.#listener = () => set(this.#matches, this.#query.matches); | ||
this.#query.addEventListener('change', this.#listener); | ||
} | ||
|
||
this.#subscribers += 1; | ||
|
||
return () => { | ||
tick().then(() => { | ||
// Only count down after timeout, else we would reach 0 before our own render effect reruns, | ||
// but reach 1 again when the tick callback of the prior teardown runs. That would mean we | ||
// re-subcribe unnecessarily and create a memory leak because the old subscription is never cleaned up. | ||
this.#subscribers -= 1; | ||
|
||
if (this.#subscribers === 0) { | ||
this.#query.removeEventListener('change', this.#listener); | ||
} | ||
}); | ||
}; | ||
}); | ||
} | ||
|
||
return get(this.#matches); | ||
} | ||
|
||
/** @param {string} query */ | ||
constructor(query) { | ||
this.#query = window.matchMedia(query); | ||
console.log('MediaQuery.constructor', query, this.#query); | ||
this.#matches.v = this.#query.matches; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters