@@ -17,6 +17,36 @@ var Immutable = require('immutable');
1717var assign = require ( 'object-assign' ) ;
1818var guid = require ( '../../utils/guid' ) ;
1919
20+ const themes = {
21+ light : {
22+ container : {
23+ color : '#000000' ,
24+ background : '#eeeeee' ,
25+ } ,
26+ addButton : {
27+ color : '#000000' ,
28+ } ,
29+ } ,
30+ dark : {
31+ container : {
32+ color : '#ffffff' ,
33+ background : '#222222' ,
34+ } ,
35+ addButton : {
36+ color : '#ffffff' ,
37+ } ,
38+ filterButton : {
39+ color : '#ffffff' ,
40+ } ,
41+ filterButtonActive : {
42+ backgroundColor : 'crimson' ,
43+ } ,
44+ } ,
45+ } ;
46+ const ThemeContext = React . createContext ( ) ;
47+ ThemeContext . Provider . displayName = 'ThemeContext.Provider' ;
48+ ThemeContext . Consumer . displayName = 'ThemeContext.Consumer' ;
49+
2050class Todos extends React . Component {
2151 constructor ( props ) {
2252 super ( props ) ;
@@ -86,16 +116,26 @@ class Todos extends React.Component {
86116
87117 render ( ) {
88118 return (
89- < div style = { styles . container } >
90- < h1 style = { styles . title } > Things to do</ h1 >
91- < NewTodo onAdd = { this . onAdd . bind ( this ) } />
92- < TodoItems
93- todos = { this . state . todos }
94- filter = { this . state . filter }
95- onToggleComplete = { this . toggleComplete . bind ( this ) }
96- />
97- < Filter onSort = { this . sort . bind ( this ) } onFilter = { this . changeFilter . bind ( this ) } filter = { this . state . filter } />
98- </ div >
119+ < ThemeContext . Consumer >
120+ { theme => {
121+ const mergedStyles = {
122+ container : { ...styles . container , ...theme . container } ,
123+ title : { ...styles . title , ...theme . title } ,
124+ } ;
125+ return (
126+ < div style = { mergedStyles . container } >
127+ < h1 style = { mergedStyles . title } > Things to do</ h1 >
128+ < NewTodo onAdd = { this . onAdd . bind ( this ) } />
129+ < TodoItems
130+ todos = { this . state . todos }
131+ filter = { this . state . filter }
132+ onToggleComplete = { this . toggleComplete . bind ( this ) }
133+ />
134+ < Filter onSort = { this . sort . bind ( this ) } onFilter = { this . changeFilter . bind ( this ) } filter = { this . state . filter } />
135+ </ div >
136+ ) ;
137+ } }
138+ </ ThemeContext . Consumer >
99139 ) ;
100140 }
101141}
@@ -123,18 +163,27 @@ class NewTodo extends React.Component {
123163
124164 render ( ) {
125165 return (
126- < div style = { styles . newContainer } >
127- < input
128- style = { styles . newInput }
129- value = { this . state . text }
130- placeholder = "Add new item"
131- onKeyDown = { e => this . checkEnter ( e ) }
132- onChange = { e => this . setState ( { text : e . target . value } ) }
133- />
134- < button onClick = { this . submit . bind ( this ) } style = { styles . addButton } >
135- +
136- </ button >
137- </ div >
166+ < ThemeContext . Consumer >
167+ { theme => {
168+ const mergedStyles = {
169+ newContainer : { ...styles . newContainer , ...theme . newContainer } ,
170+ newInput : { ...styles . newInput , ...theme . newInput } ,
171+ addButton : { ...styles . addButton , ...theme . addButton } ,
172+ } ;
173+ return (
174+ < div style = { mergedStyles . newContainer } >
175+ < input
176+ style = { mergedStyles . newInput }
177+ value = { this . state . text }
178+ placeholder = "Add new item"
179+ onKeyDown = { e => this . checkEnter ( e ) }
180+ onChange = { e => this . setState ( { text : e . target . value } ) }
181+ />
182+ < button onClick = { this . submit . bind ( this ) } style = { mergedStyles . addButton } > +</ button >
183+ </ div >
184+ ) ;
185+ } }
186+ </ ThemeContext . Consumer >
138187 ) ;
139188 }
140189}
@@ -189,9 +238,7 @@ class HoverHighlight extends React.Component {
189238 < div
190239 onMouseOver = { ( ) => this . setState ( { hover : true } ) }
191240 onMouseOut = { ( ) => this . setState ( { hover : false } ) }
192- style = { assign ( { } , this . props . style , {
193- backgroundColor : this . state . hover ? '#eee' : 'transparent' ,
194- } ) } >
241+ style = { assign ( { } , this . props . style ) } >
195242 { this . props . children }
196243 </ div >
197244 ) ;
@@ -200,17 +247,28 @@ class HoverHighlight extends React.Component {
200247
201248function Filter ( props ) {
202249 var options = [ 'All' , 'Completed' , 'Remaining' ] ;
250+
203251 return (
204- < div style = { styles . filter } >
205- { options . map ( text => (
206- < button
207- key = { text }
208- style = { assign ( { } , styles . filterButton , text === props . filter && styles . filterButtonActive ) }
209- onClick = { props . onFilter . bind ( null , text ) }
210- > { text } </ button >
211- ) ) }
212- { /*<button onClick={this.props.onSort} style={styles.filterButton}>Sort</button>*/ }
213- </ div >
252+ < ThemeContext . Consumer >
253+ { theme => {
254+ const mergedStyles = {
255+ filterButton : { ...styles . filterButton , ...theme . filterButton } ,
256+ filterButtonActive : { ...styles . filterButtonActive , ...theme . filterButtonActive } ,
257+ } ;
258+ return (
259+ < div style = { styles . filter } >
260+ { options . map ( text => (
261+ < button
262+ key = { text }
263+ style = { assign ( { } , mergedStyles . filterButton , text === props . filter && mergedStyles . filterButtonActive ) }
264+ onClick = { props . onFilter . bind ( null , text ) }
265+ > { text } </ button >
266+ ) ) }
267+ { /*<button onClick={this.props.onSort} style={styles.filterButton}>Sort</button>*/ }
268+ </ div >
269+ ) ;
270+ } }
271+ </ ThemeContext . Consumer >
214272 ) ;
215273}
216274
@@ -278,8 +336,8 @@ var styles = {
278336
279337 iframeWatermark : {
280338 position : 'absolute' ,
281- top : 20 ,
282- left : 20 ,
339+ top : 30 ,
340+ left : 10 ,
283341 fontSize : 25 ,
284342 color : '#ccc' ,
285343 fontFamily : 'sans-serif' ,
@@ -397,29 +455,47 @@ for (var mCount = 200; mCount--;) {
397455
398456
399457class Wrap extends React . Component {
458+ constructor ( props , context ) {
459+ super ( props , context ) ;
460+ this . state = { theme : themes . light } ;
461+ this . handleToggleButtonClick = this . handleToggleButtonClick . bind ( this ) ;
462+ }
463+
464+ handleToggleButtonClick ( ) {
465+ const { theme } = this . state ;
466+ this . setState ( {
467+ theme : theme === themes . dark
468+ ? themes . light
469+ : themes . dark ,
470+ } ) ;
471+ }
472+
400473 render ( ) {
474+ const { theme } = this . state ;
475+ const themeButtonLabel = `Switch to ${ theme === themes . dark ? 'light' : 'dark' } theme` ;
401476 return (
402- < div >
403- < div style = { styles . iframeWatermark } >
404- this is an iframe
477+ < ThemeContext . Provider value = { this . state . theme } >
478+ < div >
479+ < button onClick = { this . handleToggleButtonClick } > { themeButtonLabel } </ button >
480+ < div style = { styles . iframeWatermark } > this is an iframe</ div >
481+ { /* for testing highlighing in the presence of multiple scrolls
482+ {long(long(long()))} {/* */ }
483+ < Todos />
484+ { /*<span thing={someVal}/>
485+ <Target count={1}/>
486+ <span awesome={2} thing={[1,2,3]} more={{2:3}}/>
487+ <span val={null}/>
488+ <span val={undefined}/>
489+ <div><</div>*/ }
490+ < DeeplyNested />
491+ < PropTester awesome = { 2 } />
492+ < PropTester { ...emptyProps } />
493+ < PropTester { ...primitiveProps } />
494+ < PropTester { ...complexProps } />
495+ < PropTester { ...uninspectableProps } />
496+ < PropTester massiveMap = { massiveMap } />
405497 </ div >
406- { /* for testing highlighing in the presence of multiple scrolls
407- {long(long(long()))} {/* */ }
408- < Todos />
409- { /*<span thing={someVal}/>
410- <Target count={1}/>
411- <span awesome={2} thing={[1,2,3]} more={{2:3}}/>
412- <span val={null}/>
413- <span val={undefined}/>
414- <div><</div>*/ }
415- < DeeplyNested />
416- < PropTester awesome = { 2 } />
417- < PropTester { ...emptyProps } />
418- < PropTester { ...primitiveProps } />
419- < PropTester { ...complexProps } />
420- < PropTester { ...uninspectableProps } />
421- < PropTester massiveMap = { massiveMap } />
422- </ div >
498+ </ ThemeContext . Provider >
423499 ) ;
424500 }
425501}
0 commit comments