File tree Expand file tree Collapse file tree 3 files changed +57
-5
lines changed Expand file tree Collapse file tree 3 files changed +57
-5
lines changed Original file line number Diff line number Diff line change @@ -129,6 +129,11 @@ Keys of media query objects are camel-cased and numeric values automatically get
129129See the [ json2mq docs] ( https://github.com/akiran/json2mq/blob/master/README.md#usage ) for more
130130examples of queries you can construct using objects.
131131
132+ An optional ` targetWindow ` prop can be specified if you want the ` query ` to be
133+ evaluated against a different window object than the one the code is running in.
134+ This can be useful for example if you are rendering part of your component tree
135+ to an iframe or [ a popup window] ( https://hackernoon.com/using-a-react-16-portal-to-do-something-cool-2a2d627b0202 ) .
136+
132137If you're curious about how react-media differs from
133138[ react-responsive] ( https://github.com/contra/react-responsive ) , please see
134139[ this comment] ( https://github.com/ReactTraining/react-media/issues/70#issuecomment-347774260 ) .
Original file line number Diff line number Diff line change @@ -14,11 +14,13 @@ class Media extends React.Component {
1414 PropTypes . arrayOf ( PropTypes . object . isRequired )
1515 ] ) . isRequired ,
1616 render : PropTypes . func ,
17- children : PropTypes . oneOfType ( [ PropTypes . node , PropTypes . func ] )
17+ children : PropTypes . oneOfType ( [ PropTypes . node , PropTypes . func ] ) ,
18+ targetWindow : PropTypes . object
1819 } ;
1920
2021 static defaultProps = {
21- defaultMatches : true
22+ defaultMatches : true ,
23+ targetWindow : window
2224 } ;
2325
2426 state = {
@@ -28,13 +30,20 @@ class Media extends React.Component {
2830 updateMatches = ( ) => this . setState ( { matches : this . mediaQueryList . matches } ) ;
2931
3032 componentWillMount ( ) {
31- if ( typeof window !== "object" ) return ;
32-
3333 let { query } = this . props ;
34+ const { targetWindow } = this . props ;
35+
36+ if ( typeof targetWindow !== "object" ) return ;
37+
38+ if ( ! targetWindow . matchMedia ) {
39+ throw new Error (
40+ 'You passed a `targetWindow` prop to `Media` that does not have a `matchMedia` function.'
41+ ) ;
42+ }
3443
3544 if ( typeof query !== "string" ) query = json2mq ( query ) ;
3645
37- this . mediaQueryList = window . matchMedia ( query ) ;
46+ this . mediaQueryList = targetWindow . matchMedia ( query ) ;
3847 this . mediaQueryList . addListener ( this . updateMatches ) ;
3948 this . updateMatches ( ) ;
4049 }
Original file line number Diff line number Diff line change @@ -122,6 +122,44 @@ describe("A <Media>", () => {
122122 } ) ;
123123 } ) ;
124124
125+ describe ( "when a custom targetWindow prop is passed" , ( ) => {
126+ beforeEach ( ( ) => {
127+ window . matchMedia = createMockMediaMatcher ( true ) ;
128+ } ) ;
129+
130+ it ( "renders its child" , ( ) => {
131+ const testWindow = {
132+ matchMedia : createMockMediaMatcher ( false )
133+ } ;
134+
135+ const element = (
136+ < Media query = "" targetWindow = { testWindow } >
137+ { matches => ( matches ? < div > hello</ div > : < div > goodbye</ div > ) }
138+ </ Media >
139+ ) ;
140+
141+ ReactDOM . render ( element , node , ( ) => {
142+ expect ( node . firstChild . innerHTML ) . toMatch ( / g o o d b y e / ) ;
143+ } ) ;
144+ } ) ;
145+
146+ describe ( "when a non-window prop is passed for targetWindow" , ( ) => {
147+ it ( "errors with a useful message" , ( ) => {
148+ const notAWindow = { } ;
149+
150+ const element = (
151+ < Media query = "" targetWindow = { notAWindow } >
152+ { matches => ( matches ? < div > hello</ div > : < div > goodbye</ div > ) }
153+ </ Media >
154+ ) ;
155+
156+ expect ( ( ) => {
157+ ReactDOM . render ( element , node , ( ) => { } ) ;
158+ } ) . toThrow ( "does not have a `matchMedia` function" ) ;
159+ } ) ;
160+ } )
161+ } ) ;
162+
125163 describe ( "rendered on the server" , ( ) => {
126164 beforeEach ( ( ) => {
127165 window . matchMedia = createMockMediaMatcher ( true ) ;
You can’t perform that action at this time.
0 commit comments