<div id="root"></div>
body {
  background: #46484b;
}

.container {
  max-width: 600px;
  margin: auto;
}

/* SWITCH */
.cube-switch {
  border-radius: 10px;
  border: 1px solid rgba(0, 0, 0, 0.4);
  box-shadow: 0 0 8px rgba(0, 0, 0, 0.6), inset 0 100px 50px rgba(255, 255, 255, 0.1);
  /* Prevents clics on the back */
  cursor: default;
  float: left;
  position: relative;
  vertical-align: top;
  overflow: hidden;
  /* Prevents clics on the back */
  pointer-events: none;
  padding: 20px;
  margin-top: 10px;
  background: #333;
}

/* The switch */
.cube-switch .switch {
  border: 1px solid rgba(0, 0, 0, 0.6);
  border-radius: 0.7em;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3), inset 0 -7px 0 rgba(0, 0, 0, 0.2), inset 0 50px 10px rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.2);
  display: block;
  width: 60px;
  height: 60px;
  position: relative;
  background: #666;
  transition: all 0.2s ease-out;
  /* Allows click */
  cursor: pointer;
  pointer-events: auto;
}

/* SWITCH Active State */
.cube-switch.active .switch {
  background: #333;
  box-shadow: inset 0 6px 0 rgba(255, 255, 255, 0.1), inset 0 7px 0 rgba(0, 0, 0, 0.2), inset 0 -50px 10px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(205, 205, 205, 0.1);
}

.cube-switch.active:after,
.cube-switch.active:before {
  background: #333;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.1), inset 1px 2px 1px rgba(0, 0, 0, 0.5), inset 3px 6px 2px rgba(200, 200, 200, 0.1), inset -1px -2px 1px rgba(0, 0, 0, 0.3);
}

.cube-switch.active .switch:after,
.cube-switch.active .switch:before {
  background: #222;
  border: none;
  margin-top: 0;
  height: 1px;
}

.cube-switch .switch-state {
  display: block;
  position: absolute;
  left: 40%;
  color: #FFF;
  font-size: .5em;
  text-align: center;
}

.cube-switch .switch-state.on {
  bottom: 15%;
}

.cube-switch .switch-state.off {
  top: 15%;
}

.light-bulb {
  position: relative;
  width: 150px;
  height: 150px;
  float: right;
  background: url(https://lh4.googleusercontent.com/-katLGTSCm2Q/UJC0_N7XCrI/AAAAAAAABq0/6GxNfNW-Ra4/s300/lightbulb.png) no-repeat right 0;
  cursor: crosshair;
  z-index: 800;
}

.light-bulb:after {
  content: "";
  position: absolute;
  top: 0;
  width: 100%;
  height: 100%;
  background: inherit;
  background-position: 0 0;
  opacity: 0;
  transition: all 0.5s;
}

.light-bulb.on:after {
  opacity: 1;
}
class Switch extends React.Component {
    render() {
        var switchClass = this.props.isOn ? "cube-switch active" : "cube-switch";
        return (
          <div className={switchClass}>
            <span className="switch" onClick={this.props.onSwitched}>
              <span className="switch-state off">Off</span>
              <span className="switch-state on">On</span>
            </span>
          </div>
        );
    }
}

class Bulb extends React.Component {
  render() {
    let lightClass = this.props.isOn ? "light-bulb on" : "light-bulb off";
    return (
      <div className={lightClass}></div>
    )
  }
}

class App extends React.Component {
    constructor() {
      super();
      
      this.state = {
        switchOn: false
      }
      
      this.toggleSwitch = this.toggleSwitch.bind(this);
    }
  
    toggleSwitch() {
      this.setState({ switchOn: !this.state.switchOn });
    }
  
    render() {
      return (
        <div>
          <Switch isOn={this.state.switchOn} onSwitched={this.toggleSwitch} />
          <Bulb isOn={this.state.switchOn} />
        </div>
      )
    }
}

ReactDOM.render(<App/>, document.getElementById('root'));
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. //unpkg.com/react/umd/react.development.js
  2. //unpkg.com/react-dom/umd/react-dom.development.js