Skip to content

Instantly share code, notes, and snippets.

@reyronald
Last active November 7, 2025 10:26
Show Gist options
  • Select an option

  • Save reyronald/5f12da082bd0d30b7f4e08669d3be50a to your computer and use it in GitHub Desktop.

Select an option

Save reyronald/5f12da082bd0d30b7f4e08669d3be50a to your computer and use it in GitHub Desktop.
import { mediaQueryListSet } from "client/src/hooks/useMediaQuery";
import { useEffect } from "react";
const modifiedCSSRules: Map<CSSMediaRule, string> = new Map();
export function useEmulateMediaPrint() {
useEffect(() => {
for (const styleSheet of document.styleSheets) {
for (const cssRule of styleSheet.cssRules) {
if (cssRule instanceof CSSStyleRule) {
for (const innerCssRule of cssRule.cssRules) {
if (innerCssRule instanceof CSSMediaRule) {
handleCssRule(innerCssRule);
}
}
} else if (cssRule instanceof CSSMediaRule) {
handleCssRule(cssRule);
}
}
}
for (const mediaQueryList of mediaQueryListSet) {
if (mediaQueryList.media === "print") {
mediaQueryList.dispatchEvent(new MediaQueryListEvent("change", { matches: true }));
}
}
return () => {
for (const [cssRule, mediaText] of modifiedCSSRules) {
cssRule.media.mediaText = mediaText;
}
modifiedCSSRules.clear();
};
}, []);
}
function handleCssRule(cssRule: CSSMediaRule) {
const hasPrint = Array.from(cssRule.media).some(
(media) => media === "print" || media === "not print",
);
if (hasPrint) {
modifiedCSSRules.set(cssRule, cssRule.media.mediaText);
cssRule.media.mediaText = cssRule.media.mediaText.replaceAll("print", "screen");
}
}
import { useState, useEffect } from "react";
export const mediaQueryListSet: Set<MediaQueryList> = new Set();
export const useMediaQuery = (query: string) => {
const [matches, setMatches] = useState(window.matchMedia(query).matches);
useEffect(() => {
const mediaQueryList = window.matchMedia(query);
setMatches(mediaQueryList.matches);
const listener = (e: MediaQueryListEvent) => setMatches(e.matches);
mediaQueryList.addEventListener("change", listener);
mediaQueryListSet.add(mediaQueryList);
return () => {
mediaQueryList.removeEventListener("change", listener);
mediaQueryListSet.delete(mediaQueryList);
};
}, [query]);
return matches;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment