1
1
import PropTypes from 'prop-types'
2
2
import React , { createContext , Component } from 'react'
3
3
import { withTheme } from 'emotion-theming'
4
+ import { reduceObj } from '@exah/utils'
5
+
6
+ const listenForChanges = ( target , fn ) => {
7
+ fn ( )
8
+
9
+ target . addListener ( fn )
10
+ return ( ) => target . removeListener ( fn )
11
+ }
4
12
5
13
const INITIAL_STATE = {
6
14
currentMediaKey : [ ]
@@ -19,14 +27,14 @@ class CurrentMediaProvider extends Component {
19
27
}
20
28
state = INITIAL_STATE
21
29
listeners = [ ]
22
- setCurrentMedia = ( mediaKey , mediaQueryList ) => {
30
+ setCurrentMedia = ( key , mediaQueryList ) => {
23
31
this . setState ( ( prevState ) => {
24
32
const nextMediaKey = prevState . currentMediaKey . slice ( 0 )
25
33
26
34
if ( mediaQueryList . matches ) {
27
- nextMediaKey . push ( mediaKey )
35
+ nextMediaKey . push ( key )
28
36
} else {
29
- const index = nextMediaKey . indexOf ( mediaKey )
37
+ const index = nextMediaKey . indexOf ( key )
30
38
if ( index === - 1 ) return
31
39
nextMediaKey . splice ( index , 1 )
32
40
}
@@ -37,19 +45,14 @@ class CurrentMediaProvider extends Component {
37
45
} )
38
46
}
39
47
componentDidMount ( ) {
40
- const { media, theme } = this . props
48
+ const media = this . props . media || this . props . theme . media || { }
41
49
42
- const mediaList = Object . entries ( media || theme . media || { } ) . map (
43
- ( [ mediaKey , mediaQuery ] ) => [ mediaKey , window . matchMedia ( mediaQuery ) ]
44
- )
45
-
46
- this . listeners = mediaList . map ( ( [ mediaKey , mediaQueryList ] ) => {
47
- this . setCurrentMedia ( mediaKey , mediaQueryList )
48
- const listener = ( ) => this . setCurrentMedia ( mediaKey , mediaQueryList )
50
+ this . listeners = reduceObj ( ( acc , key , query ) => {
51
+ const mediaQueryList = window . matchMedia ( query )
52
+ const listener = ( ) => this . setCurrentMedia ( key , mediaQueryList )
49
53
50
- mediaQueryList . addListener ( listener )
51
- return ( ) => mediaQueryList . removeListener ( listener )
52
- } )
54
+ return [ ...acc , listenForChanges ( mediaQueryList , listener ) ]
55
+ } , [ ] , media )
53
56
}
54
57
componentWillUnmount ( ) {
55
58
this . listeners . map ( ( fn ) => fn ( ) )
0 commit comments