Created
March 16, 2018 23:10
-
-
Save nickdandakis/b7c49983b08ba8e719badecf926ac849 to your computer and use it in GitHub Desktop.
Apple MacOS window controls
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from 'react'; | |
import classnames from 'classnames'; | |
const ALT = 18; | |
class MacOSWindowControls extends Component { | |
state = { | |
altKeyDown: false, | |
blurred: false, | |
fullscreen: false, | |
}; | |
componentDidMount() { | |
document.addEventListener('keydown', this.handleKeyDown); | |
document.addEventListener('keyup', this.handleKeyUp); | |
window.addEventListener('blur', this.handleBlur); | |
window.addEventListener('focus', this.handleFocus); | |
} | |
componentWillUnmount() { | |
document.removeEventListener('keydown', this.handleKeyDown); | |
document.removeEventListener('keyup', this.handleKeyUp); | |
window.removeEventListener('blur', this.handleBlur); | |
window.removeEventListener('focus', this.handleFocus); | |
} | |
handleKeyDown = (event) => { | |
if (event.keyCode === ALT) { | |
this.setState({ | |
...this.state, | |
altKeyDown: true, | |
}); | |
} | |
} | |
handleKeyUp = (event) => { | |
if (event.keyCode === ALT) { | |
this.setState({ | |
...this.state, | |
altKeyDown: false, | |
}); | |
} | |
} | |
handleBlur = () => { | |
this.setState({ | |
...this.state, | |
blurred: true, | |
}); | |
} | |
handleFocus = () => { | |
this.setState({ | |
...this.state, | |
blurred: false, | |
}); | |
} | |
handleMaximize = (event) => { | |
const { | |
onMaximize, | |
onFullscreen, | |
} = this.props; | |
const { | |
altKeyDown, | |
fullscreen, | |
} = this.state; | |
if (altKeyDown && !fullscreen) { | |
console.log('a'); | |
onMaximize(); | |
} else { | |
this.setState({ | |
...this.state, | |
fullscreen: !this.state.fullscreen, | |
}); | |
onFullscreen(); | |
} | |
} | |
render() { | |
const { | |
onClose, | |
onMinimize, | |
} = this.props; | |
const { | |
blurred, | |
fullscreen, | |
altKeyDown, | |
} = this.state; | |
const className = classnames({ | |
'macos-window-controls': true, | |
blurred, | |
fullscreen, | |
'alt-key-down': altKeyDown, | |
}); | |
return ( | |
<div className={className}> | |
<div className="close" onClick={onClose}> | |
<svg x="0px" y="0px" viewBox="0 0 6 6"> | |
<polygon fill="#860006" points="6,1 6,0 5,0 3,2 1,0 0,0 0,1 2,3 0,5 0,6 1,6 3,4 5,6 6,6 6,5 4,3" /> | |
</svg> | |
</div> | |
<div className="minimize" onClick={onMinimize}> | |
<svg x="0px" y="0px" viewBox="0 0 7 2"> | |
<rect fill="#9d5615" width={7} height={2} /> | |
</svg> | |
</div> | |
<div className="maximize" onClick={this.handleMaximize}> | |
<svg className="fullscreen-svg" x="0px" y="0px" viewBox="0 0 6 6"> | |
<path fill="#006413" d="M0,1.4v3.8c0.4,0,0.8,0.3,0.8,0.8h3.8L0,1.4z" /> | |
<path fill="#006413" d="M6,4.6V0.8C5.6,0.8,5.2,0.4,5.2,0H1.4L6,4.6z" /> | |
</svg> | |
<svg className="exit-fullscreen-svg" x="0px" y="0px" viewBox="0 0 6 6"> | |
<path fill="#006413" d="M3,0v2.5c0.3,0,0.5,0.2,0.5,0.5H6L3,0z" /> | |
<path fill="#006413" d="M3,6V3.5C2.7,3.5,2.5,3.3,2.5,3H0L3,6z" /> | |
</svg> | |
<svg className="maximize-svg" x="0px" y="0px" viewBox="0 0 7.9 7.9"> | |
<polygon fill="#006413" points="7.9,4.5 7.9,3.4 4.5,3.4 4.5,0 3.4,0 3.4,3.4 0,3.4 0,4.5 3.4,4.5 3.4,7.9 4.5,7.9 4.5,4.5" /> | |
</svg> | |
</div> | |
<style jsx>{` | |
.macos-window-controls { | |
-webkit-app-region: no-drag; | |
&:hover { | |
& svg { | |
opacity: 1 !important; | |
} | |
} | |
&.blurred:not(:hover) > * { | |
background-color: #dcdcdc; | |
border-color: #d1d1d1; | |
} | |
&.alt-key-down:not(.fullscreen) { | |
& .fullscreen-svg { | |
display: none; | |
} | |
& .maximize-svg { | |
display: block; | |
} | |
} | |
&.fullscreen { | |
& .fullscreen-svg { | |
display: none; | |
} | |
& .exit-fullscreen-svg { | |
display: block; | |
} | |
} | |
} | |
.close, | |
.minimize, | |
.maximize { | |
float: left; | |
width: 10px; | |
height: 10px; | |
border-radius: 50%; | |
margin: 6px 4px; | |
line-height: 0; | |
box-sizing: content-box; | |
} | |
.close { | |
border: 1px solid #e94343; | |
background-color: #ff5d5b; | |
margin-left: 6px; | |
&:active { | |
border-color: #b43737; | |
background-color: #c64845; | |
} | |
& svg { | |
width: 6px; | |
height: 6px; | |
margin-top: 2px; | |
margin-left: 2px; | |
opacity: 0; | |
} | |
} | |
& .minimize { | |
border: 1px solid #e5a03a; | |
background-color: #ffbc45; | |
&:active { | |
border-color: #b07b2e; | |
background-color: #c38e34; | |
} | |
& svg { | |
width: 8px; | |
height: 8px; | |
margin-top: 1px; | |
margin-left: 1px; | |
opacity: 0; | |
} | |
} | |
.maximize { | |
border: 1px solid #13ad3e; | |
background-color: #00c94f; | |
&:active { | |
border-color: #138532; | |
background-color: #009a3c; | |
} | |
& .fullscreen-svg { | |
width: 6px; | |
height: 6px; | |
margin-top: 2px; | |
margin-left: 2px; | |
opacity: 0; | |
} | |
& .exit-fullscreen-svg { | |
width: 10px; | |
height: 10px; | |
margin-top: 0; | |
margin-left: 0; | |
opacity: 0; | |
display: none; | |
} | |
& .maximize-svg { | |
width: 8px; | |
height: 8px; | |
margin-top: 1px; | |
margin-left: 1px; | |
opacity: 0; | |
display: none; | |
} | |
} | |
`}</style> | |
</div> | |
); | |
} | |
}; | |
export default MacOSWindowControls; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment