Files
sendou.ink/app/hooks/useMediaQuery.ts
Kalle 10feace73d
Some checks failed
E2E Tests / e2e (push) Has been cancelled
Tests and checks on push / run-checks-and-tests (push) Has been cancelled
Updates translation progress / update-translation-progress-issue (push) Has been cancelled
Drive layout breakpoints with media and container queries instead of resize listeners
2026-09-02 22:04:54 +03:00

26 lines
821 B
TypeScript

import * as React from "react";
const subscribers = new Map<string, (onChange: () => void) => () => void>();
/** Whether the media `query` matches, re-rendering only when the match flips. `serverValue` on the server and the hydration render. */
export function useMediaQuery(query: string, serverValue = false) {
return React.useSyncExternalStore(
subscriberFor(query),
() => window.matchMedia(query).matches,
() => serverValue,
);
}
function subscriberFor(query: string) {
let subscribe = subscribers.get(query);
if (!subscribe) {
subscribe = (onChange) => {
const mediaQueryList = window.matchMedia(query);
mediaQueryList.addEventListener("change", onChange);
return () => mediaQueryList.removeEventListener("change", onChange);
};
subscribers.set(query, subscribe);
}
return subscribe;
}