mirror of
https://github.com/Hopiu/vue-material.git
synced 2026-04-20 06:41:04 +00:00
Add initial styles and detach and attach menu on click
This commit is contained in:
parent
18b3aac2ac
commit
d2c7d2603e
6 changed files with 169 additions and 110 deletions
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
5
src/components/mdMenu/mdMenuContent.vue
Normal file
5
src/components/mdMenu/mdMenuContent.vue
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<template>
|
||||
<div class="md-menu-content">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
13
src/components/mdMenu/mdMenuItem.vue
Normal file
13
src/components/mdMenu/mdMenuItem.vue
Normal 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>
|
||||
Loading…
Reference in a new issue