Skip to content

Instantly share code, notes, and snippets.

@andrewgremlich
Created March 3, 2017 22:53
Show Gist options
  • Save andrewgremlich/c7cb28897f0a59b617f644dc24f7b3e0 to your computer and use it in GitHub Desktop.
Save andrewgremlich/c7cb28897f0a59b617f644dc24f7b3e0 to your computer and use it in GitHub Desktop.
Utilizes Web Components to make an menu-drawer for mobile devices. Primarily to be used with Progressive Web Apps.
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hamburger Menu</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<menu-drawer>
<img src="https://material.io/guidelines/static/images/callouts/default.svg">
<img src="https://material.io/guidelines/static/images/callouts/default.svg">
<img src="https://material.io/guidelines/static/images/callouts/default.svg">
<img src="https://material.io/guidelines/static/images/callouts/default.svg">
</menu-drawer>
<script src="menu-drawer.js"></script>
</body>
</html>
const temp = `
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
#menu-container {
background-color: #e2e2e2;
position: absolute;
bottom: 0;
width: 100%;
}
::slotted(img) {
width: 60px;
margin: 10px;
}
.arrow {
margin-top: 20px;
width: 0;
height: 0;
border-left: 30px solid transparent;
border-right: 30px solid transparent;
border-bottom: 20px solid #33547b;
border-radius: 8px;
}
.dis {
position: relative;
top: -5px;
width: 0;
height: 0;
border-left: 30px solid transparent;
border-right: 30px solid transparent;
border-bottom: 15px solid #e2e2e2;
}
#menu-items,
#arrow-container {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: nowrap;
}
.rotated180 {
transform: rotate(180deg) translate(0px, -10px);
}
.hidden {
transform: translate(0px, 60px);
}
@keyframes turn-downward {
from {
transform: rotate(0deg);
}
to {
transform: rotate(180deg) translate(0px, -10px);
}
}
@keyframes turn-upward {
from {
transform: rotate(180deg) translate(0px, -10px);
}
to {
transform: rotate(0deg);
}
}
@keyframes hide {
from {
transform: translate(0px, 0px);
}
to {
transform: translate(0px, 60px);
}
}
@keyframes show {
from {
transform: translate(0px, 60px);
}
to {
transform: translate(0px, 0px);
}
}
</style>
<div data-opened="false" id="menu-container" class="hidden">
<div id="arrow-container">
<div id="flex-child">
<div class="arrow"></div>
<div class="dis"></div>
</div>
</div>
<div id="menu-items">
<slot>
</slot>
</div>
</div>
`
class menu_drawer extends HTMLElement {
constructor() {
super()
this._shadowRoot = this.attachShadow({
mode: 'open'
})
this._shadowRoot.innerHTML = temp
this.onclick = e => {
console.log()
let container = this._shadowRoot.querySelector("#menu-container"),
arrow = this._shadowRoot.querySelector("#arrow-container"),
isOpened = container.getAttribute("data-opened") === "true"
if (e.target.localName !== "img"|| e.target.localName !== "a") {
if (isOpened) {
arrow.style.animation = "turn-upward 0.2s"
arrow.className = ""
container.setAttribute("data-opened", "false")
container.style.animation = "hide 0.35s"
container.className = "hidden"
} else {
arrow.style.animation = "turn-downward 0.2s"
arrow.className = "rotated180"
container.setAttribute("data-opened", "true")
container.style.animation = "show 0.35s"
container.className = ""
}
}
}
}
}
customElements.define('menu-drawer', menu_drawer)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment