Skip to content

Commit

Permalink
fix(MdApp): right drawer, fully reactive (#1493)
Browse files Browse the repository at this point in the history
* fix(MdApp): right drawer

BREAKING CHANGE: Replace useless props `mdLeft` with `!this.mdRight`

fix #1204

* fix(MdAppDrawer): right drawer supporting

BREAKING CHANGE: no more than one drawer in a MdApp

* fix(MdDrawerRightPrevious): right drawer styles

use an previous element for styling container with right drawer with similar css codes

* fix(MdDrawer): Temporary style

* fix(MdAppSideDrawer): correct component name

* fix(MdApp): reactive persistent drawer

fully reactive drawer
  • Loading branch information
VdustR authored and marcosmoura committed May 13, 2018
1 parent ddee303 commit 3ac16c7
Show file tree
Hide file tree
Showing 10 changed files with 205 additions and 35 deletions.
39 changes: 35 additions & 4 deletions src/components/MdApp/MdApp.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<script>
import Vue from 'vue'
import MdAppSideDrawer from './MdAppSideDrawer'
import MdAppInternalDrawer from './MdAppInternalDrawer'
import MdDrawerRightPrevious from '../MdDrawer/MdDrawerRightPrevious';
const componentTypes = [
'md-app-toolbar',
Expand All @@ -12,16 +14,41 @@
return componentOptions && componentTypes.includes(componentOptions.tag)
}
function buildSlots (children, context, functionalContext, options) {
function buildSlots (children, context, functionalContext, options, createElement) {
let slots = []
let hasDrawer = false
if (children) {
children.forEach(child => {
const data = child.data
const componentOptions = child.componentOptions
if ((data && componentTypes.includes(data.slot)) || isValidChild(componentOptions)) {
child.data.slot = data.slot || componentOptions.tag
if (componentOptions.tag === 'md-app-drawer') {
if (hasDrawer) {
Vue.util.warn(`There shouldn't be more than one drawer in a MdApp at one time.`)
return
}
hasDrawer = true
let nativeMdRight = componentOptions.propsData.mdRight
let mdRight = nativeMdRight === '' || !!nativeMdRight
child.data.slot += `-${mdRight ? 'right' : 'left'}`
child.key = JSON.stringify({
'persistent': child.data.attrs['md-persistent'],
'permanent': child.data.attrs['md-permanent']
})
if (mdRight) {
const drawerRightPrevious = createElement(MdDrawerRightPrevious, { props: {...child.data.attrs}})
drawerRightPrevious.data.slot = 'md-app-drawer-right-previous'
slots.push(drawerRightPrevious)
}
}
child.data.provide = options.Ctor.options.provide
child.context = context
child.functionalContext = functionalContext
Expand Down Expand Up @@ -54,7 +81,7 @@
render (createElement, { children, props, data }) {
let appComponent = MdAppSideDrawer
const { context, functionalContext, componentOptions } = createElement(appComponent)
const slots = buildSlots(children, context, functionalContext, componentOptions)
const slots = buildSlots(children, context, functionalContext, componentOptions, createElement)
const drawers = getDrawers(slots)
drawers.forEach(drawer => {
Expand Down Expand Up @@ -157,7 +184,9 @@
&.md-permanent-card + .md-app-scroller .md-content {
@include md-layout-small-and-up {
padding-left: 0;
padding-right: 0;
border-left: none;
border-right: none;
}
}
}
Expand All @@ -167,6 +196,7 @@
@include md-layout-small-and-up {
border-left: 1px solid transparent;
border-right: 1px solid transparent;
}
> p {
Expand All @@ -185,8 +215,9 @@
display: flex;
overflow: auto;
transform: translate3D(0, 0, 0);
transition: padding-left .4s $md-transition-default-timing;
will-change: padding-left;
transition: padding-left .4s $md-transition-default-timing,
padding-right .4s $md-transition-default-timing;
will-change: padding-left, padding-right;
}
.md-app-scroller {
Expand Down
48 changes: 40 additions & 8 deletions src/components/MdApp/MdAppDrawer.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<md-drawer class="md-app-drawer" v-bind="$attrs" v-on="$listeners">
<md-drawer class="md-app-drawer" :md-active="mdActive && initialized" v-bind="$attrs" v-on="$listeners" :md-right="mdRight" ref="drawer">
<slot />
</md-drawer>
</template>
Expand All @@ -13,8 +13,19 @@
mdActive: null,
mode: null,
submode: null
}
},
initialized: false
}),
props: {
mdRight: {
type: Boolean,
default: false
},
mdActive: {
type: Boolean,
default: false
}
},
computed: {
visible () {
return this.drawerElement.mdActive
Expand All @@ -24,7 +35,7 @@
},
submode () {
return this.drawerElement.submode
}
},
},
watch: {
visible (visible) {
Expand All @@ -36,6 +47,9 @@
},
submode (submode) {
this.MdApp.drawer.submode = submode
},
mdRight (right) {
this.MdApp.drawer.right = right
}
},
methods: {
Expand All @@ -45,17 +59,35 @@
}
return 0
}
},
mounted () {
this.$nextTick().then(() => {
this.drawerElement = this.$children[0]
},
updateDrawerData () {
this.MdApp.drawer.width = this.getDrawerWidth()
this.MdApp.drawer.active = this.visible
this.MdApp.drawer.mode = this.mode
this.MdApp.drawer.submode = this.submode
this.MdApp.drawer.right = this.mdRight
},
clearDrawerData () {
this.MdApp.drawer.width = 0
this.MdApp.drawer.active = false
this.MdApp.drawer.mode = 'temporary'
this.MdApp.drawer.submode = null
this.MdApp.drawer.initialWidth = 0
},
},
mounted () {
this.$nextTick().then(() => {
this.MdApp.drawer.initialWidth = this.$el.offsetWidth
this.drawerElement = this.$refs.drawer
this.updateDrawerData()
this.initialized = true
})
},
updated () {
this.drawerElement = this.$refs.drawer
},
beforeDestroy () {
this.clearDrawerData()
}
}
</script>
4 changes: 3 additions & 1 deletion src/components/MdApp/MdAppInternalDrawer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
<slot name="md-app-toolbar"></slot>

<main class="md-app-container md-flex md-layout-row" :style="[containerStyles, contentStyles]" :class="[$mdActiveTheme, scrollerClasses]">
<slot name="md-app-drawer"></slot>
<slot name="md-app-drawer-left"></slot>
<slot name="md-app-drawer-right-previous"></slot>
<div class="md-app-scroller md-layout-column md-flex" :class="[$mdActiveTheme, scrollerClasses]">
<slot name="md-app-content"></slot>
</div>
<slot name="md-app-drawer-right"></slot>
</main>
</div>
</template>
Expand Down
25 changes: 16 additions & 9 deletions src/components/MdApp/MdAppMixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ export default {
initialWidth: 0,
active: false,
mode: 'temporary',
width: 0
submode: null,
width: 0,
right: false
}
}
}),
Expand All @@ -61,16 +63,21 @@ export default {
isFixed () {
return this.mdMode && this.mdMode !== 'fixed'
},
isMini () {
isDrawerMini () {
return this.MdApp.drawer.mode === 'persistent' && this.MdApp.drawer.submode === 'mini'
},
contentStyles () {
contentPadding () {
const drawer = this.MdApp.drawer

if (drawer.active && drawer.mode === 'persistent' && drawer.submode === 'full') {
return {
'padding-left': drawer.width
}
if (this.MdApp.drawer.active && this.MdApp.drawer.mode === 'persistent' && this.MdApp.drawer.submode === 'full') {
return this.MdApp.drawer.width
}

return 0
},
contentStyles () {
return {
[`padding-${this.MdApp.drawer.right ? 'right' : 'left'}`]: this.contentPadding
}
},
containerStyles () {
Expand All @@ -80,8 +87,8 @@ export default {
styles['margin-top'] = this.MdApp.toolbar.initialHeight + 'px'
}

if (this.isMini) {
styles['padding-left'] = !this.MdApp.drawer.active ? this.MdApp.drawer.initialWidth + 'px' : 0
if (this.isDrawerMini) {
styles[`padding-${this.MdApp.drawer.right ? 'right' : 'left'}`] = !this.MdApp.drawer.active ? this.MdApp.drawer.initialWidth + 'px' : 0
}

return styles
Expand Down
8 changes: 5 additions & 3 deletions src/components/MdApp/MdAppSideDrawer.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
<template>
<div class="md-app md-app-side-drawer md-layout-row" :class="[appClasses, $mdActiveTheme]">
<slot name="md-app-drawer"></slot>

<slot name="md-app-drawer-left"></slot>
<slot name="md-app-drawer-right-previous"></slot>
<main class="md-app-container md-flex md-layout-column" :class="[$mdActiveTheme, scrollerClasses]" :style="contentStyles" @scroll.passive="handleScroll">
<slot name="md-app-toolbar"></slot>
<div class="md-app-scroller md-layout-column md-flex" :class="[$mdActiveTheme, scrollerClasses]" :style="containerStyles" @scroll.passive="handleScroll">
<slot name="md-app-content"></slot>
</div>
</main>

<slot name="md-app-drawer-right"></slot>
</div>
</template>

Expand All @@ -16,7 +18,7 @@
import MdAppMixin from './MdAppMixin'
export default new MdComponent({
name: 'MdAppInternalSideDrawer',
name: 'MdAppSideDrawer',
mixins: [MdAppMixin]
})
</script>
Expand Down
4 changes: 4 additions & 0 deletions src/components/MdApp/MdAppToolbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@
}
}
.md-app-toolbar {
min-height: 64px;
}
.md-overlap {
.md-app-toolbar {
height: 196px;
Expand Down
1 change: 1 addition & 0 deletions src/components/MdContent/theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

.md-app & {
@include md-theme-property(border-left-color, divider, background);
@include md-theme-property(border-right-color, divider, background);
}
}
}
48 changes: 39 additions & 9 deletions src/components/MdDrawer/MdDrawer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
MdOverlay
},
props: {
mdLeft: Boolean,
mdRight: Boolean,
mdPermanent: {
type: String,
Expand Down Expand Up @@ -49,7 +48,7 @@
computed: {
drawerClasses () {
let classes = {
'md-left': this.mdLeft,
'md-left': !this.mdRight,
'md-right': this.mdRight,
'md-temporary': this.isTemporary,
'md-persistent': this.mdPersistent,
Expand Down Expand Up @@ -165,8 +164,16 @@
}
&.md-temporary {
+ .md-app-container .md-content {
border-left: none;
&.md-left {
+ .md-app-container .md-content {
border-left: none;
}
}
&.md-right-previous {
+ .md-app-container .md-content {
border-right: none;
}
}
&.md-active {
Expand Down Expand Up @@ -216,22 +223,45 @@
&.md-persistent {
&:not(.md-active) {
+ .md-app-container .md-content {
border-left: none;
&.md-left {
+ .md-app-container .md-content {
border-left: none;
}
}
&.md-right-previous {
+ .md-app-container .md-content {
border-right: none;
}
}
}
}
&.md-persistent-mini {
border-right: 1px solid;
transform: translate3D(0, 64px, 0);
transition: .3s $md-transition-stand-timing;
transition-property: transform, width;
will-change: transform, box-shadow;
&.md-left {
border-right: 1px solid;
}
&.md-right {
border-left: 1px solid;
}
&.md-active {
+ .md-app-container .md-content {
border-left: none;
&.md-left {
+ .md-app-container .md-content {
border-left: none;
}
}
&.md-right-previous {
+ .md-app-container .md-content {
border-right: none;
}
}
}
Expand Down
Loading

2 comments on commit 3ac16c7

@goatandsheep
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hold on: "BREAKING CHANGE: no more than one drawer in a MdApp"

I need to have two drawers in my app: one main drawer for navigation and a second drawer for information about items, similar to Facebook messenger. I was trying to have my left drawer full and right drawer clipped. But now that won't be possible at all?

@VdustR
Copy link
Member Author

@VdustR VdustR commented on 3ac16c7 May 28, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can't be implement for now.

full drawer is using MdAppSideDrawer and clipped is using MdAppInternalDrawer.

function hasInternalDrawer (attrs) {

Please sign in to comment.