<div id="root"></div>
@use postcss-cssnext;
@use postcss-simple-vars;
@use postcss-custom-media;
@use postcss-nested;
@use postcss-mixins;
@use lost;
body {
background-color: #333;
font-family: "Roboto";
}
main {
max-width: 100vw;
width: 100%;
height: 100vh;
display: flex;
flex: 1;
flex-flow: column nowrap;
align-items: center;
justify-content: center;
}
button {
background-color: #666;
border-radius: 5px;
color: white;
border: 0;
padding: 20px;
bottom: 50%;
font-weight: bold;
cursor: pointer;
text-transform: uppercase;
transition: 0.25s all;
max-width: 200px;
width: 100%;
&:hover {
background-color: #F07818;
}
}
ol {
list-style-type: none;
display: flex;
flex-flow: row;
width: 100%;
max-width: 500px;
padding: 0;
justify-content: space-around;
align-items: center;
margin: 0 0 20px;
& li {
flex: 0 0 auto;
}
}
.bulb {
background-color: #888;
border-radius: 50%;
min-width: 20px;
min-height: 20px;
padding: 10px;
display: block;
text-align: center;
box-shadow: 0 2px 0 0 rgba(0, 0, 0, 0.5);
position: relative;
&.pure:before {
content: 'P';
font-weight: bold;
color: white;
}
&:after {
position: absolute;
width: 100%;
background-color: #D36112;
height: 5px;
content: '';
z-index: -1;
top: 50%;
left: 50%;
transform: translate(5px, -50%);
}
&:last-child:after {
content: none;
}
&.on {
background-color: #FCEBB6;
box-shadow: 0 0 3px 6px rgba(230,219,151, 0.4);
}
}
View Compiled
// Create new LightContext. LightContext will return a Provider and Consumer
const LightContext = React.createContext('areLightsOn');
class LightProvider extends React.Component {
render(){
// Allow Provider to set 'value' as whatever 'areLightsOn' prop is passed in
return (
<LightContext.Provider value={ this.props.areLightsOn } >
{ this.props.children }
</LightContext.Provider>
)
}
}
// 'areLightsOn' are passed in as a prop
const Bulb = ({ children, className, areLightsOn })=> {
const lightStateClassName = areLightsOn ? 'on' : 'off';
const classNames = `bulb ${className} ${lightStateClassName}`;
return (
<li className={classNames}>{children}</li>
);
}
// Add a 'Consumer' to take current 'areLightsOn' state
class LightBulb extends React.Component {
render(){
return (
<LightContext.Consumer>
{ areLightsOn => (
<Bulb {...this.props} areLightsOn={areLightsOn} />
)}
</LightContext.Consumer>
);
}
};
// Add a 'Consumer' to take current 'areLightsOn' state
class PureLightBulb extends React.PureComponent {
render(){
return (
<LightContext.Consumer>
{ areLightsOn => (
<Bulb className="pure" {...this.props} areLightsOn={areLightsOn} />
)}
</LightContext.Consumer>
);
}
}
class Wire extends React.Component {
render(){
return (
<ol>
<LightBulb />
<PureLightBulb />
<LightBulb />
<LightBulb />
<LightBulb />
<PureLightBulb />
<PureLightBulb />
<PureLightBulb />
</ol>
)
}
}
class Lights extends React.PureComponent {
constructor(props){
super(props);
this.state = {
areLightsOn: false
};
this.toggleLights = this.toggleLights.bind(this);
}
// Remove 'getChildContext', no longer need with new context
toggleLights(){
this.setState({
areLightsOn: ! this.state.areLightsOn
});
}
render(){
return (
<main>
{/* Wrap Wire in new LightProvider. Pass in state to be utilized by context */}
<LightProvider areLightsOn={ this.state.areLightsOn }>
<Wire />
</LightProvider>
{/* Update this provider to be the opposite */}
<LightProvider areLightsOn={ ! this.state.areLightsOn }>
<Wire />
</LightProvider>
<button type="button" onClick={this.toggleLights}>
Toggle Lights
</button>
</main>
);
}
}
// Remove 'childContextTypes', no longer need with new context
ReactDOM.render(<Lights />, document.getElementById('root'));
View Compiled
This Pen doesn't use any external CSS resources.