Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mobile nav: main menu fixes #320

Merged
merged 9 commits into from
Oct 10, 2019
Merged
387 changes: 284 additions & 103 deletions packages/mobile-top-nav/src/assets/img/media-menu-images.js

Large diffs are not rendered by default.

232 changes: 153 additions & 79 deletions packages/mobile-top-nav/src/media-menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,124 +3,198 @@ import { LitElement, html, css } from 'lit-element';
import './media-slider';
import './assets/img/media-menu-images';

const menuSelection = [
{
icon: 'web',
label: 'Wayback Machine',
},
{
icon: 'texts',
label: 'Texts',
},
{
icon: 'video',
label: 'Video',
},
{
icon: 'audio',
label: 'Audio',
},
{
icon: 'software',
label: 'Software',
},
{
icon: 'images',
label: 'Images',
},
{
icon: 'more',
label: 'More',
},
];

class MediaMenu extends LitElement {
static get properties() {
return {
mediaMenuOpen: { type: Boolean },
mediaMenuAnimate: { type: Boolean },
mediaSliderOpen: { type: Boolean },
mediaSliderAnimate: { type: Boolean }
mediaSliderAnimate: { type: Boolean },
selected: { type: String },
iisa marked this conversation as resolved.
Show resolved Hide resolved
};
}

constructor() {
super();
this.mediaSliderOpen = false;
this.mediaSliderAnimate = false;
this.selectedMenuOption = '';
}

updated(changedProperties) {
const { mediaMenuOpen, mediaSliderOpen } = this;
const menuClosed =
changedProperties.has('mediaMenuOpen') &&
changedProperties.get('mediaMenuOpen') &&
!mediaMenuOpen;

if (menuClosed && mediaSliderOpen) {
this.mediaSliderOpen = false;
this.mediaSliderAnimate = false;
this.selected = '';
}
}

mediaSlider() {
// Only keep side menu open until menu closed
// Shift menu downwards as per button clicked
closeMediaSlider() {
this.mediaSliderAnimate = true;
this.mediaSliderOpen = !this.mediaSliderOpen;
this.mediaSliderOpen = false;
this.selectedMenuOption = '';
}

toggleMediaSlider() {
if (!this.mediaSliderOpen) {
this.mediaSliderAnimate = true;
this.mediaSliderOpen = !this.mediaSliderOpen;
}
}

select(mediatype) {
const currentSelection = this.selected;

if (currentSelection === mediatype) {
this.closeMediaSlider();
return;
}

this.selectedMenuOption = mediatype;
this.toggleMediaSlider();
}

get mediaMenuOptionsTemplate() {
const buttons = menuSelection.map(({ icon: mediatype, label }) => {
const selected = this.selectedMenuOption === mediatype ? 'selected' : '';
return html`
<button class="menu-item ${selected}" @click="${this.select.bind(this, mediatype)}">
<span class="icon"
><mediamenu-image
type="${mediatype}"
fill="${selected ? 'white' : ''}"
></mediamenu-image
></span>
<span class="label">${label}</span>
</button>
`;
});
return buttons;
}

render() {
const mediaMenuClass = this.mediaMenuOpen ? 'media-menu open slide-in' : this.mediaMenuAnimate ? 'media-menu slide-out' : 'media-menu';
const mediaMenuHidden = this.mediaMenuOpen ? 'false' : 'true';
const mediaMenuExpanded = this.mediaMenuOpen ? 'true' : 'false';
let mediaMenuClass = 'initial';
if (this.mediaMenuOpen) {
mediaMenuClass = 'open';
}
if (!this.mediaMenuOpen && this.mediaMenuAnimate) {
mediaMenuClass = 'closed';
}
const mediaMenuHidden = Boolean(!this.mediaMenuOpen).toString();
const mediaMenuExpanded = Boolean(this.mediaMenuOpen).toString();

return html`
<nav
class="${mediaMenuClass}"
aria-hidden="${mediaMenuHidden}"
aria-expanded="${mediaMenuExpanded}"
>
<!-- Include icon and name inline in a button-->
<div class="grid">
<button tabindex="-1" @click="${this.mediaSlider}"><div><mediamenu-image type="waybackMachine"></mediamenu-image></div></button>
<button><div>Wayback Machine</div></button>
<button tabindex="-1" @click="${this.mediaSlider}"><div><mediamenu-image type="texts"></mediamenu-image></button>
<button><div>Texts</div></button>
<button tabindex="-1" @click="${this.mediaSlider}"><div><mediamenu-image type="video"></mediamenu-image></div></button>
<button><div>Video</div></button>
<button tabindex="-1" @click="${this.mediaSlider}"><div><mediamenu-image type="audio"></mediamenu-image></div></button>
<button><div>Audio</div></button>
<button tabindex="-1" @click="${this.mediaSlider}"><div><mediamenu-image type="software"></mediamenu-image></div></button>
<button><div>Software</div></button>
<button tabindex="-1" @click="${this.mediaSlider}"><div><mediamenu-image type="images"></mediamenu-image></div></button>
<button><div>Images</div></button>
<button tabindex="-1" @click="${this.mediaSlider}"><div><mediamenu-image type="more"></mediamenu-image></div></button>
<button><div>More</div></button>
</div>
</nav>
<media-slider ?mediaSliderOpen="${this.mediaSliderOpen}" ?mediaSliderAnimate="${this.mediaSliderAnimate}"></media-slider>
<nav
class="media-menu tx-slide ${mediaMenuClass}"
aria-hidden="${mediaMenuHidden}"
aria-expanded="${mediaMenuExpanded}"
>
<div class="menu-group">
${this.mediaMenuOptionsTemplate}
<media-slider
?mediaSliderOpen="${this.mediaSliderOpen}"
?mediaSliderAnimate="${this.mediaSliderAnimate}"
></media-slider>
</div>
</nav>
`;
}

static get styles() {
return css`
button:focus {
outline-color: var(--link-color);
outline-width: 0.1rem;
outline-style: auto;
}
.media-menu {
width: 100%;
height: 500px;
background-color: var(--black);
color: var(--white);
margin: 0;
font-size: 20px;
font-family: "Helvetica Neue";
transform: translate(0, -1000px);
overflow: hidden;
}
.media-menu button {
position: relative;
background: none;
color: inherit;
border: none;
font: inherit;
cursor: pointer;
text-align: left;
z-index: 5;
.media-menu.tx-slide {
transition-property: max-height;
transition-duration: 1s;
transition-timing-function: ease;
}
.open {
transform: translate(0, 0);
z-index: 1;
.media-menu.tx-slide.open {
max-height: 100vh;
}
@keyframes slide-in {
0% {
transform: translate(0, -1000px);
}
100% {
transform: translate(0, 0);
}
.media-menu.tx-slide.initial,
.media-menu.tx-slide.closed {
max-height: 0;
}
@keyframes slide-out {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(0, -1000px);
}
.media-menu.tx-slide.closed {
transition-duration: 0.1s;
}
.slide-in {
animation: slide-in 0.5s forwards;
.media-menu .menu-group {
height: 80vh;
}
.slide-out {
animation: slide-out 0.5s forwards;
.media-menu .menu-item {
width: 100%;
background: transparent;
font-size: inherit;
cursor: pointer;
height: 12%;
border: none;
text-align: left;
padding: 0;
}
.grid {
padding: 10px;
display: grid;
grid-template-columns: 50px 300px;
.media-menu .menu-item > .label {
color: var(--grey999);
text-align: left;
display: inline;
}
.grid div {
height: 40px;
padding: 10px;
.media-menu .menu-item > .icon {
display: inline-flex;
align-items: center;
justify-content: center;
height: 100%;
width: 8%;
}
a {
display: inline;
color: var(--white);
text-decoration: none;
.menu-item.selected .icon {
background-color: var(--grey20);
border-radius: 17% 0 0 17%;
}
`;
`;
}
}

Expand Down
Loading