@wordpress/compose
Version:
WordPress higher-order components (HOCs).
8 lines (7 loc) • 3.91 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../../../src/hooks/use-media-query/index.ts"],
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { useSyncExternalStore } from '@wordpress/element';\n\ntype MQLSubscriber = {\n\tsubscribe: ( onStoreChange: () => void ) => () => void;\n\tgetValue: () => boolean;\n};\n\n// One subscriber per (window, query). The underlying MediaQueryList lives\n// inside the subscriber's closure; a single `change` listener fans out to\n// every React consumer via an in-JS `Set` to avoid the per-consumer\n// `addEventListener` cost (~85 ms during a large-post editor mount).\nconst perWindowCache = new WeakMap< Window, Map< string, MQLSubscriber > >();\n\nconst EMPTY_SUBSCRIBER: MQLSubscriber = {\n\tsubscribe: () => () => {},\n\tgetValue: () => false,\n};\n\nfunction getMQLSubscriber(\n\tview: Window | undefined,\n\tquery?: string\n): MQLSubscriber {\n\tif ( ! view || ! query || typeof view.matchMedia !== 'function' ) {\n\t\treturn EMPTY_SUBSCRIBER;\n\t}\n\n\tlet queryCache = perWindowCache.get( view );\n\tif ( ! queryCache ) {\n\t\tqueryCache = new Map();\n\t\tperWindowCache.set( view, queryCache );\n\t}\n\n\tconst cached = queryCache.get( query );\n\tif ( cached ) {\n\t\treturn cached;\n\t}\n\n\tconst mediaQueryList = view.matchMedia( query );\n\tconst listeners = new Set< () => void >();\n\tconst notify = () => {\n\t\tfor ( const listener of listeners ) {\n\t\t\tlistener();\n\t\t}\n\t};\n\n\tconst subscriber: MQLSubscriber = {\n\t\tsubscribe( onStoreChange ) {\n\t\t\tif ( listeners.size === 0 ) {\n\t\t\t\t// Avoid a fatal error when browsers don't support `addEventListener` on MediaQueryList.\n\t\t\t\tmediaQueryList.addEventListener?.( 'change', notify );\n\t\t\t}\n\t\t\tlisteners.add( onStoreChange );\n\t\t\treturn () => {\n\t\t\t\tlisteners.delete( onStoreChange );\n\t\t\t\tif ( listeners.size === 0 ) {\n\t\t\t\t\tmediaQueryList.removeEventListener?.( 'change', notify );\n\t\t\t\t}\n\t\t\t};\n\t\t},\n\t\tgetValue() {\n\t\t\treturn mediaQueryList.matches;\n\t\t},\n\t};\n\n\tqueryCache.set( query, subscriber );\n\treturn subscriber;\n}\n\n/**\n * Runs a media query and returns its value when it changes.\n *\n * @param [query] Media Query.\n * @param [view] Window instance, else default to global window\n * @return return value of the media query.\n */\nexport default function useMediaQuery(\n\tquery?: string,\n\t// Resolve the default lazily so SSR (where `window` is undeclared) does not\n\t// throw a ReferenceError when this default expression is evaluated.\n\tview: Window | undefined = typeof window !== 'undefined'\n\t\t? window\n\t\t: undefined\n): boolean {\n\tconst source = getMQLSubscriber( view, query );\n\n\treturn useSyncExternalStore(\n\t\tsource.subscribe,\n\t\tsource.getValue,\n\t\t() => false\n\t);\n}\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,qBAAqC;AAWrC,IAAM,iBAAiB,oBAAI,QAAgD;AAE3E,IAAM,mBAAkC;AAAA,EACvC,WAAW,MAAM,MAAM;AAAA,EAAC;AAAA,EACxB,UAAU,MAAM;AACjB;AAEA,SAAS,iBACR,MACA,OACgB;AAChB,MAAK,CAAE,QAAQ,CAAE,SAAS,OAAO,KAAK,eAAe,YAAa;AACjE,WAAO;AAAA,EACR;AAEA,MAAI,aAAa,eAAe,IAAK,IAAK;AAC1C,MAAK,CAAE,YAAa;AACnB,iBAAa,oBAAI,IAAI;AACrB,mBAAe,IAAK,MAAM,UAAW;AAAA,EACtC;AAEA,QAAM,SAAS,WAAW,IAAK,KAAM;AACrC,MAAK,QAAS;AACb,WAAO;AAAA,EACR;AAEA,QAAM,iBAAiB,KAAK,WAAY,KAAM;AAC9C,QAAM,YAAY,oBAAI,IAAkB;AACxC,QAAM,SAAS,MAAM;AACpB,eAAY,YAAY,WAAY;AACnC,eAAS;AAAA,IACV;AAAA,EACD;AAEA,QAAM,aAA4B;AAAA,IACjC,UAAW,eAAgB;AAC1B,UAAK,UAAU,SAAS,GAAI;AAE3B,uBAAe,mBAAoB,UAAU,MAAO;AAAA,MACrD;AACA,gBAAU,IAAK,aAAc;AAC7B,aAAO,MAAM;AACZ,kBAAU,OAAQ,aAAc;AAChC,YAAK,UAAU,SAAS,GAAI;AAC3B,yBAAe,sBAAuB,UAAU,MAAO;AAAA,QACxD;AAAA,MACD;AAAA,IACD;AAAA,IACA,WAAW;AACV,aAAO,eAAe;AAAA,IACvB;AAAA,EACD;AAEA,aAAW,IAAK,OAAO,UAAW;AAClC,SAAO;AACR;AASe,SAAR,cACN,OAGA,OAA2B,OAAO,WAAW,cAC1C,SACA,QACO;AACV,QAAM,SAAS,iBAAkB,MAAM,KAAM;AAE7C,aAAO;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA,IACP,MAAM;AAAA,EACP;AACD;",
"names": []
}