UNPKG

2.13 kBPlain TextView Raw
1function noop() {}
2
3export interface MediaMatching {
4 (mediaQuery: string): Partial<MediaQueryList>;
5}
6
7export default class MatchMedia {
8 originalMatchMedia: (mediaQuery: string) => MediaQueryList;
9 private isUsingMockMatchMedia = false;
10
11 mock(media: MediaMatching = defaultMatcher) {
12 if (this.isUsingMockMatchMedia) {
13 throw new Error(
14 'You tried to mock window.matchMedia when it was already mocked.',
15 );
16 }
17
18 this.originalMatchMedia = window.matchMedia;
19 this.isUsingMockMatchMedia = true;
20
21 this.setMedia(media);
22 }
23
24 restore() {
25 if (!this.isUsingMockMatchMedia) {
26 throw new Error(
27 'You tried to restore window.matchMedia when it was already restored.',
28 );
29 }
30
31 window.matchMedia = this.originalMatchMedia;
32 this.isUsingMockMatchMedia = false;
33 }
34
35 isMocked() {
36 return this.isUsingMockMatchMedia;
37 }
38
39 setMedia(media: MediaMatching = defaultMatcher) {
40 this.ensureMatchMediaIsMocked();
41 window.matchMedia = (query: string) => mediaQueryList(media(query));
42 }
43
44 private ensureMatchMediaIsMocked() {
45 if (!this.isUsingMockMatchMedia) {
46 throw new Error(
47 'You must call matchMedia.mock() before interacting with the mock matchMedia.',
48 );
49 }
50 }
51}
52
53function defaultMatcher(): MediaQueryList {
54 return {
55 media: '',
56 addListener: noop,
57 addEventListener: noop,
58 removeListener: noop,
59 removeEventListener: noop,
60 onchange: noop,
61 dispatchEvent: () => false,
62 matches: false,
63 };
64}
65
66export function mediaQueryList(
67 values: Partial<MediaQueryList>,
68): MediaQueryList {
69 // Explictly state a return type as TypeScript does not attempt to shrink the
70 // type when using Object spread. Without the explicit return type TypeScript
71 // exports a type that exposes the internals of `MediaQueryList` (which
72 // changed in TS 3.1.0).
73 // This ensures that this function can be used in projects that use any
74 // version of Typescript instead of only <3.1.0 or >= 3.1.0 depending on the
75 // version that this library was compiled using.
76 return {
77 ...defaultMatcher(),
78 ...values,
79 };
80}