Instantly share code, notes, and snippets.
Utilizes Web Components to make an menu-drawer for mobile devices. Primarily to be used with Progressive Web Apps.
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
<!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> |
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
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