Add initial styles and detach and attach menu on click

This commit is contained in:
Marcos Moura 2016-10-19 21:33:31 -02:00
parent 18b3aac2ac
commit d2c7d2603e
6 changed files with 169 additions and 110 deletions

View file

@ -1,8 +1,18 @@
<template>
<demo-page label="Components - Menu">
<div slot="examples">
<demo-example label="Default">
<md-menu></md-menu>
<demo-example label="Default" height="400">
<md-menu>
<md-button class="md-icon-button" md-menu-trigger>
<md-icon>more_vert</md-icon>
</md-button>
<md-menu-content>
<md-menu-item>My Item 1</md-menu-item>
<md-menu-item>My Item 2</md-menu-item>
<md-menu-item>My Item 3</md-menu-item>
</md-menu-content>
</md-menu>
</demo-example>
</div>
@ -15,95 +25,3 @@
</div>
</demo-page>
</template>
<style lang="scss">
@import '../../../../src/core/stylesheets/variables.scss';
.phone-viewport {
width: 360px;
height: 540px;
margin-right: 16px;
display: inline-block;
position: relative;
overflow: hidden;
background-color: #fff;
border: 1px solid rgba(#000, .12);
}
.custom-list {
.md-list-action {
position: absolute;
top: 8px;
right: 16px;
pointer-events: auto;
z-index: 2;
}
.md-icon {
color: rgba(#000, .26);
}
}
.complete-example {
height: 540px;
display: flex;
flex-flow: column;
position: relative;
overflow: hidden;
z-index: 1;
.md-fab {
margin: 0;
position: absolute;
bottom: -20px;
left: 16px;
box-shadow: $material-shadow-5dp;
}
.md-toolbar {
.md-icon {
color: #014e70;
}
}
.md-title {
color: #fff;
}
.md-list {
overflow: auto;
}
.md-list-action .md-icon {
color: rgba(#000, .26);
}
.md-avatar-icon .md-icon {
color: #fff !important;
}
.md-sidenav .md-list-text-container > :nth-child(2) {
color: rgba(#fff, .54);
}
.md-account-header {
.md-list-item:hover .md-button:hover {
background-color: inherit;
}
.md-avatar-list .md-list-item-container:hover {
background: none !important;
}
}
}
</style>
<script>
export default {
methods: {
toggleSidenav() {
this.$refs.sidebar.toggle();
}
}
};
</script>

View file

@ -1,8 +1,12 @@
import mdMenu from './mdMenu.vue';
import mdMenuItem from './mdMenuItem.vue';
import mdMenuContent from './mdMenuContent.vue';
import mdMenuTheme from './mdMenu.theme';
export default function install(Vue) {
Vue.component('md-menu', Vue.extend(mdMenu));
Vue.component('md-menu-item', Vue.extend(mdMenuItem));
Vue.component('md-menu-content', Vue.extend(mdMenuContent));
Vue.material.styles.push(mdMenuTheme);
}

View file

@ -1,5 +1,93 @@
@import '../../core/stylesheets/variables.scss';
.md-select {
$menu-base-width: 56px;
.md-menu-content {
min-width: $menu-base-width * 1.5;
max-width: $menu-base-width * 3;
min-height: 64px;
max-height: 256px;
padding: 8px 0;
display: flex;
flex-flow: column;
justify-content: stretch;
align-content: stretch;
pointer-events: none;
overflow-x: hidden;
overflow-y: auto;
position: absolute;
top: 0;
left: 0;
z-index: 120;
background-color: #fff;
border-radius: 2px;
box-shadow: $material-shadow-2dp;
opacity: 0;
transform: scale3D(.85, .7, 1);
transition: $swift-ease-out-duration $swift-ease-out-timing-function,
opacity .25s $swift-ease-in-timing-function,
top .25s $swift-ease-in-timing-function,
transform 0s .25s $swift-ease-in-timing-function;
color: rgba(#212121, .87);
&.md-active {
pointer-events: auto;
opacity: 1;
transform: scale3D(1, 1, 1);
transform-origin: center top;
transition: $swift-ease-out;
transition-duration: .25s;
transition-property: opacity, transform, top;
> * {
opacity: 1;
transition: $swift-ease-in;
transition-duration: .15s;
transition-delay: .1s;
}
}
&.md-size-1 {
max-width: $menu-base-width * 1.5;
}
@for $i from 2 through 7 {
&.md-size-#{$i} {
max-width: $menu-base-width * $i;
}
}
> * {
opacity: 0;
transition: $swift-ease-out;
transition-duration: .25s;
}
}
.md-menu-item {
height: 48px;
min-height: 48px;
padding: 0 16px;
display: flex;
flex-flow: column;
justify-content: center;
overflow: hidden;
cursor: pointer;
position: relative;
transform: translate3D(0, 0, 0);
transition: $swift-ease-out;
font-size: 16px;
line-height: 1.2em;
text-overflow: ellipsis;
white-space: nowrap;
&:hover {
background-color: rgba(#000, .12);
}
.md-menu-item-content {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}

View file

@ -1,5 +1,5 @@
<template>
<div class="md-menu" :class="classes">
<div class="md-menu">
<slot></slot>
</div>
</template>
@ -9,28 +9,59 @@
<script>
export default {
props: {
mdSize: {
type: [Number, String],
default: 1
}
},
data() {
return {
};
},
computed: {
classes() {
return {
};
watch: {
mdSize(current, previous) {
this.removeLastMenuContentClass(previous);
this.addNewMenuContentClass();
}
},
methods: {
validateMenu() {
if (!this.menuContent) {
this.$destroy();
throw new Error('You should have a md-menu-content inside your menu.');
}
if (!this.menuTrigger) {
this.$destroy();
throw new Error('You should have an element with a md-menu-trigger attribute inside your menu.');
}
},
removeLastMenuContentClass(size) {
this.menuContent.classList.remove('md-size-' + size);
},
addNewMenuContentClass() {
this.menuContent.classList.add('md-size-' + this.mdSize);
},
toggle() {
if (this.active) {
this.menuContent.classList.remove('md-active');
document.body.removeChild(this.menuContent);
this.active = false;
} else {
document.body.appendChild(this.menuContent);
getComputedStyle(this.menuContent).display;
this.menuContent.classList.add('md-active');
this.active = true;
}
}
},
mounted() {
this.menuTrigger = this.$el.querySelector('[md-menu-trigger]');
this.menuContent = this.$el.querySelector('.md-menu-content');
this.validateMenu();
this.addNewMenuContentClass();
},
beforeDestroy() {
this.menuContent.parentNode.removeChild(this.menuContent);
this.menuTrigger.addEventListener('click', this.toggle);
}
};
</script>

View file

@ -0,0 +1,5 @@
<template>
<div class="md-menu-content">
<slot></slot>
</div>
</template>

View file

@ -0,0 +1,13 @@
<template>
<div class="md-menu-item" v-md-ink-ripple>
<div class="md-menu-item-content">
<slot></slot>
</div>
</div>
</template>
<script>
export default {
};
</script>