Skip to content

Commit

Permalink
small refactor (#81)
Browse files Browse the repository at this point in the history
* small refactor

* merge
  • Loading branch information
TGlide authored Jun 7, 2024
1 parent a84aa88 commit a7dc36d
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 33 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* A class that takes a predicate determine if a browser API is supported.
* A class that takes a predicate to determine if a browser API is supported.
*
* Useful for checking if a browser API is supported before attempting to use it.
*
Expand Down
60 changes: 28 additions & 32 deletions packages/runed/src/lib/utilities/MediaQuery/MediaQuery.svelte.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { useEventListener } from "../useEventListener/useEventListener.svelte.js";
import type { Getter, MaybeGetter } from "$lib/internal/types.js";
import { extract } from "../extract/extract.js";
import type { MaybeGetter } from "$lib/internal/types.js";
import { browser } from "$lib/internal/utils/browser.js";

/**
* Take a media query (or a function that returns one if you want reactivity)
* as input and you can check if it currently matches doing `instance.match`
* Takes a media query as an input and listsens for changes to it,
* holding a reactive property with its current state.
*
* @see {@link https://runed.dev/docs/utilities/media-query}
*
Expand All @@ -13,7 +14,7 @@ import { browser } from "$lib/internal/utils/browser.js";
* const screen = new MediaQuery("(min-width: 640px)");
*
* $effect(() => {
* if (screen.match) {
* if (screen.matches) {
* console.log("The screen is less than 640px");
* }
* });
Expand All @@ -22,10 +23,10 @@ import { browser } from "$lib/internal/utils/browser.js";
* @example
* ```ts
* let media = $state("(min-width: 640px)");
* const screen = new MediaQuery(()=> media);
* const screen = new MediaQuery(() => media);
*
* $effect(() => {
* if (screen.match) {
* if (screen.matches) {
* console.log(`Media query ${media} is ${screen.match}`);
* }
* });
Expand All @@ -34,43 +35,38 @@ import { browser } from "$lib/internal/utils/browser.js";
* ```
*/
export class MediaQuery {
#matches: boolean | undefined = $state();
#propQuery: MaybeGetter<string>;
#query = $derived.by(() => extract(this.#propQuery));
#mediaQueryList: MediaQueryList = $derived(window.matchMedia(this.#query));
#effectRegistered = false;
#query_fn: Getter<string | void> = () => {};
// this will be initialized in the constructor
#query = $derived(this.#query_fn?.()) as string;
#matches: boolean | undefined = $state();

constructor(query: MaybeGetter<string>) {
this.#query_fn = typeof query === "function" ? query : () => query;
}

#matchMedia() {
const result = window.matchMedia(this.#query);
this.#matches = result.matches;
return result;
this.#propQuery = query;
}

get matches(): boolean | undefined {
// if we are in an effect and this effect has not been registered yet
// we match the current value, register the listener and return match
if ($effect.active() && !this.#effectRegistered) {
this.#matches = this.#mediaQueryList.matches;

// If we are in an effect and this effect has not been registered yet
// we match the current value, register the listener and return match
$effect(() => {
const result = this.#matchMedia();
this.#effectRegistered = true;
useEventListener(result, "change", (changed) => {
this.#matches = changed.matches;
});
return () => {
this.#effectRegistered = false;
};

useEventListener(
() => this.#mediaQueryList,
"change",
(changed) => (this.#matches = changed.matches)
);

return () => (this.#effectRegistered = false);
});
} else if (!$effect.active()) {
// otherwise if we are not in an effect and the effect has not
//been registered we just match media to get the current value
if (browser) {
this.#matchMedia();
}
} else if (!$effect.active() && browser) {
// Otherwise, just match media to get the current value
this.#matches = this.#mediaQueryList.matches;
}

return this.#matches;
}
}

0 comments on commit a7dc36d

Please sign in to comment.