Skip to content

Instantly share code, notes, and snippets.

@jonshipman
Last active February 4, 2024 22:24
Show Gist options
  • Save jonshipman/a81f98a6b2a98aed983bb0444af8a1b8 to your computer and use it in GitHub Desktop.
Save jonshipman/a81f98a6b2a98aed983bb0444af8a1b8 to your computer and use it in GitHub Desktop.
Media size dispatcher
<script lang="ts">
import { createEventDispatcher } from 'svelte';
import { ResizeStore } from './window-events';
import type { ResizeDetail } from './resize.svelte.d';
export let debounce = 0;
export let mobile: boolean | null = null;
const dispatch = createEventDispatcher<{ resize: ResizeDetail }>();
let timeout: ReturnType<typeof setTimeout>;
function mount(node: HTMLDivElement) {
const unsub = ResizeStore.subscribe(() => {
clearTimeout(timeout);
timeout = setTimeout(() => {
const visible = node.offsetParent === null;
mobile = visible;
dispatch('resize', { visible: { md: visible } });
}, debounce);
});
return {
destroy() {
clearTimeout(timeout);
unsub();
}
};
}
</script>
<div class="hidden md:block" use:mount />
import type { SvelteComponent } from 'svelte';
export interface ResizeDetail {
visible: { md: boolean };
}
export type ResizeEvent = Event & { detail: ResizeDetail };
export default class Resize extends SvelteComponent {}
/**
* Allows one listener per type in the application.
* e.g. If you have 500 InView components, you'll only have one scroll listener.
*/
function createWindowEventStore(event: string) {
const subs: Array<() => void> = [];
let listener = false;
function on() {
for (const cb of subs) {
cb();
}
}
return {
subscribe(cb: () => void) {
subs.push(cb);
cb();
if (!listener) {
window.addEventListener(event, on);
listener = true;
}
return () => {
const index = subs.findIndex((fn) => fn === cb);
subs.splice(index, 1);
if (subs.length < 1) {
window.removeEventListener(event, on);
listener = false;
}
};
}
};
}
export const ResizeStore = createWindowEventStore('resize');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment