@@ -20,6 +20,36 @@ const guid = require('../../utils/guid');
2020
2121const { unstable_trace : trace } = ScheduleTracing ;
2222
23+ const themes = {
24+ light : {
25+ container : {
26+ color : '#000000' ,
27+ background : '#eeeeee' ,
28+ } ,
29+ addButton : {
30+ color : '#000000' ,
31+ } ,
32+ } ,
33+ dark : {
34+ container : {
35+ color : '#ffffff' ,
36+ background : '#222222' ,
37+ } ,
38+ addButton : {
39+ color : '#ffffff' ,
40+ } ,
41+ filterButton : {
42+ color : '#ffffff' ,
43+ } ,
44+ filterButtonActive : {
45+ backgroundColor : 'crimson' ,
46+ } ,
47+ } ,
48+ } ;
49+ const ThemeContext = React . createContext ( ) ;
50+ ThemeContext . Provider . displayName = 'ThemeContext.Provider' ;
51+ ThemeContext . Consumer . displayName = 'ThemeContext.Consumer' ;
52+
2353class Todos extends React . Component {
2454 constructor ( props ) {
2555 super ( props ) ;
@@ -95,16 +125,26 @@ class Todos extends React.Component {
95125
96126 render ( ) {
97127 return (
98- < div style = { styles . container } >
99- < h1 style = { styles . title } > Things to do</ h1 >
100- < NewTodo onAdd = { this . onAdd . bind ( this ) } />
101- < TodoItems
102- todos = { this . state . todos }
103- filter = { this . state . filter }
104- onToggleComplete = { this . toggleComplete . bind ( this ) }
105- />
106- < Filter onSort = { this . sort . bind ( this ) } onFilter = { this . changeFilter . bind ( this ) } filter = { this . state . filter } />
107- </ div >
128+ < ThemeContext . Consumer >
129+ { theme => {
130+ const mergedStyles = {
131+ container : { ...styles . container , ...theme . container } ,
132+ title : { ...styles . title , ...theme . title } ,
133+ } ;
134+ return (
135+ < div style = { mergedStyles . container } >
136+ < h1 style = { mergedStyles . title } > Things to do</ h1 >
137+ < NewTodo onAdd = { this . onAdd . bind ( this ) } />
138+ < TodoItems
139+ todos = { this . state . todos }
140+ filter = { this . state . filter }
141+ onToggleComplete = { this . toggleComplete . bind ( this ) }
142+ />
143+ < Filter onSort = { this . sort . bind ( this ) } onFilter = { this . changeFilter . bind ( this ) } filter = { this . state . filter } />
144+ </ div >
145+ ) ;
146+ } }
147+ </ ThemeContext . Consumer >
108148 ) ;
109149 }
110150}
@@ -132,18 +172,27 @@ class NewTodo extends React.Component {
132172
133173 render ( ) {
134174 return (
135- < div style = { styles . newContainer } >
136- < input
137- style = { styles . newInput }
138- value = { this . state . text }
139- placeholder = "Add new item"
140- onKeyDown = { e => this . checkEnter ( e ) }
141- onChange = { e => this . setState ( { text : e . target . value } ) }
142- />
143- < button onClick = { this . submit . bind ( this ) } style = { styles . addButton } >
144- +
145- </ button >
146- </ div >
175+ < ThemeContext . Consumer >
176+ { theme => {
177+ const mergedStyles = {
178+ newContainer : { ...styles . newContainer , ...theme . newContainer } ,
179+ newInput : { ...styles . newInput , ...theme . newInput } ,
180+ addButton : { ...styles . addButton , ...theme . addButton } ,
181+ } ;
182+ return (
183+ < div style = { mergedStyles . newContainer } >
184+ < input
185+ style = { mergedStyles . newInput }
186+ value = { this . state . text }
187+ placeholder = "Add new item"
188+ onKeyDown = { e => this . checkEnter ( e ) }
189+ onChange = { e => this . setState ( { text : e . target . value } ) }
190+ />
191+ < button onClick = { this . submit . bind ( this ) } style = { mergedStyles . addButton } > +</ button >
192+ </ div >
193+ ) ;
194+ } }
195+ </ ThemeContext . Consumer >
147196 ) ;
148197 }
149198}
@@ -198,9 +247,7 @@ class HoverHighlight extends React.Component {
198247 < div
199248 onMouseOver = { ( ) => this . setState ( { hover : true } ) }
200249 onMouseOut = { ( ) => this . setState ( { hover : false } ) }
201- style = { assign ( { } , this . props . style , {
202- backgroundColor : this . state . hover ? '#eee' : 'transparent' ,
203- } ) } >
250+ style = { assign ( { } , this . props . style ) } >
204251 { this . props . children }
205252 </ div >
206253 ) ;
@@ -209,17 +256,28 @@ class HoverHighlight extends React.Component {
209256
210257function Filter ( props ) {
211258 var options = [ 'All' , 'Completed' , 'Remaining' ] ;
259+
212260 return (
213- < div style = { styles . filter } >
214- { options . map ( text => (
215- < button
216- key = { text }
217- style = { assign ( { } , styles . filterButton , text === props . filter && styles . filterButtonActive ) }
218- onClick = { props . onFilter . bind ( null , text ) }
219- > { text } </ button >
220- ) ) }
221- { /*<button onClick={this.props.onSort} style={styles.filterButton}>Sort</button>*/ }
222- </ div >
261+ < ThemeContext . Consumer >
262+ { theme => {
263+ const mergedStyles = {
264+ filterButton : { ...styles . filterButton , ...theme . filterButton } ,
265+ filterButtonActive : { ...styles . filterButtonActive , ...theme . filterButtonActive } ,
266+ } ;
267+ return (
268+ < div style = { styles . filter } >
269+ { options . map ( text => (
270+ < button
271+ key = { text }
272+ style = { assign ( { } , mergedStyles . filterButton , text === props . filter && mergedStyles . filterButtonActive ) }
273+ onClick = { props . onFilter . bind ( null , text ) }
274+ > { text } </ button >
275+ ) ) }
276+ { /*<button onClick={this.props.onSort} style={styles.filterButton}>Sort</button>*/ }
277+ </ div >
278+ ) ;
279+ } }
280+ </ ThemeContext . Consumer >
223281 ) ;
224282}
225283
@@ -287,8 +345,8 @@ var styles = {
287345
288346 iframeWatermark : {
289347 position : 'absolute' ,
290- top : 20 ,
291- left : 20 ,
348+ top : 30 ,
349+ left : 10 ,
292350 fontSize : 25 ,
293351 color : '#ccc' ,
294352 fontFamily : 'sans-serif' ,
@@ -406,29 +464,47 @@ for (var mCount = 200; mCount--;) {
406464
407465
408466class Wrap extends React . Component {
467+ constructor ( props , context ) {
468+ super ( props , context ) ;
469+ this . state = { theme : themes . light } ;
470+ this . handleToggleButtonClick = this . handleToggleButtonClick . bind ( this ) ;
471+ }
472+
473+ handleToggleButtonClick ( ) {
474+ const { theme } = this . state ;
475+ this . setState ( {
476+ theme : theme === themes . dark
477+ ? themes . light
478+ : themes . dark ,
479+ } ) ;
480+ }
481+
409482 render ( ) {
483+ const { theme } = this . state ;
484+ const themeButtonLabel = `Switch to ${ theme === themes . dark ? 'light' : 'dark' } theme` ;
410485 return (
411- < div >
412- < div style = { styles . iframeWatermark } >
413- this is an iframe
486+ < ThemeContext . Provider value = { this . state . theme } >
487+ < div >
488+ < button onClick = { this . handleToggleButtonClick } > { themeButtonLabel } </ button >
489+ < div style = { styles . iframeWatermark } > this is an iframe</ div >
490+ { /* for testing highlighing in the presence of multiple scrolls
491+ {long(long(long()))} {/* */ }
492+ < Todos />
493+ { /*<span thing={someVal}/>
494+ <Target count={1}/>
495+ <span awesome={2} thing={[1,2,3]} more={{2:3}}/>
496+ <span val={null}/>
497+ <span val={undefined}/>
498+ <div><</div>*/ }
499+ < DeeplyNested />
500+ < PropTester awesome = { 2 } />
501+ < PropTester { ...emptyProps } />
502+ < PropTester { ...primitiveProps } />
503+ < PropTester { ...complexProps } />
504+ < PropTester { ...uninspectableProps } />
505+ < PropTester massiveMap = { massiveMap } />
414506 </ div >
415- { /* for testing highlighing in the presence of multiple scrolls
416- {long(long(long()))} {/* */ }
417- < Todos />
418- { /*<span thing={someVal}/>
419- <Target count={1}/>
420- <span awesome={2} thing={[1,2,3]} more={{2:3}}/>
421- <span val={null}/>
422- <span val={undefined}/>
423- <div><</div>*/ }
424- < DeeplyNested />
425- < PropTester awesome = { 2 } />
426- < PropTester { ...emptyProps } />
427- < PropTester { ...primitiveProps } />
428- < PropTester { ...complexProps } />
429- < PropTester { ...uninspectableProps } />
430- < PropTester massiveMap = { massiveMap } />
431- </ div >
507+ </ ThemeContext . Provider >
432508 ) ;
433509 }
434510}
0 commit comments