Skip to content

Commit 4da9e77

Browse files
committed
feat(MdApp): create waterfall toolbars
1 parent 870030c commit 4da9e77

File tree

11 files changed

+255
-76
lines changed

11 files changed

+255
-76
lines changed

docs/app/pages/Components/App/examples/App.vue

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<template>
22
<div class="page-container">
3-
<md-app>
4-
<md-toolbar class="md-primary">
3+
<md-app md-waterfall md-mode="fixed">
4+
<md-app-toolbar class="md-primary">
55
<span class="md-title">My Title</span>
6-
</md-toolbar>
6+
</md-app-toolbar>
77

8-
<md-drawer md-permanent="full">
8+
<md-app-drawer md-permanent="full">
99
<md-toolbar class="md-transparent" md-elevation="0">
1010
Navigation
1111
</md-toolbar>
@@ -31,9 +31,9 @@
3131
<span class="md-list-item-text">Spam</span>
3232
</md-list-item>
3333
</md-list>
34-
</md-drawer>
34+
</md-app-drawer>
3535

36-
<md-content>
36+
<md-app-content>
3737
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Error quibusdam, non molestias et! Earum magnam, similique, quo recusandae placeat dicta asperiores modi sint ea repudiandae maxime? Quae non explicabo, neque.</p>
3838
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Error quibusdam, non molestias et! Earum magnam, similique, quo recusandae placeat dicta asperiores modi sint ea repudiandae maxime? Quae non explicabo, neque.</p>
3939
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Error quibusdam, non molestias et! Earum magnam, similique, quo recusandae placeat dicta asperiores modi sint ea repudiandae maxime? Quae non explicabo, neque.</p>
@@ -42,7 +42,7 @@
4242
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Error quibusdam, non molestias et! Earum magnam, similique, quo recusandae placeat dicta asperiores modi sint ea repudiandae maxime? Quae non explicabo, neque.</p>
4343
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Error quibusdam, non molestias et! Earum magnam, similique, quo recusandae placeat dicta asperiores modi sint ea repudiandae maxime? Quae non explicabo, neque.</p>
4444
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Error quibusdam, non molestias et! Earum magnam, similique, quo recusandae placeat dicta asperiores modi sint ea repudiandae maxime? Quae non explicabo, neque.</p>
45-
</md-content>
45+
</md-app-content>
4646
</md-app>
4747
</div>
4848
</template>

src/components/MdApp/MdApp.vue

+52-23
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
import MdAppInternalDrawer from './MdAppInternalDrawer'
44
55
const componentTypes = [
6-
'md-toolbar',
7-
'md-drawer',
8-
'md-content'
6+
'md-app-toolbar',
7+
'md-app-drawer',
8+
'md-app-content'
99
]
1010
1111
function buildSlots (children, context, functionalContext, options) {
@@ -21,10 +21,6 @@
2121
child.context = context
2222
child.functionalContext = functionalContext
2323
24-
if (opts.tag === 'md-content') {
25-
child.data.staticClass = 'md-flex'
26-
}
27-
2824
slots.push(child)
2925
}
3026
})
@@ -35,30 +31,34 @@
3531
3632
function getDrawer (children) {
3733
const drawerVnode = children.filter(child => {
38-
return child.componentOptions.tag === 'md-drawer'
34+
return child.componentOptions.tag === 'md-app-drawer'
3935
})
4036
4137
return drawerVnode && drawerVnode[0]
4238
}
4339
44-
function isInternal (props) {
45-
return props.mdPermanent && (props.mdPermanent === 'clipped' || props.mdPermanent === 'card')
40+
function hasInternalDrawer (attrs) {
41+
const mdPermanent = attrs && attrs['md-permanent']
42+
43+
return mdPermanent && (mdPermanent === 'clipped' || mdPermanent === 'card')
4644
}
4745
4846
export default {
4947
name: 'MdApp',
5048
functional: true,
51-
render (createElement, { children, injections }) {
49+
render (createElement, { children, props }) {
5250
let appComponent = MdAppSideDrawer
5351
const { context, functionalContext, componentOptions } = createElement(appComponent)
5452
const slots = buildSlots(children, context, functionalContext, componentOptions)
5553
const drawer = getDrawer(slots)
5654
57-
if (drawer && isInternal(drawer.componentOptions.propsData)) {
55+
if (drawer && hasInternalDrawer(drawer.data.attrs)) {
5856
appComponent = MdAppInternalDrawer
5957
}
6058
61-
return createElement(appComponent, slots)
59+
return createElement(appComponent, {
60+
attrs: props
61+
}, slots)
6262
}
6363
}
6464
</script>
@@ -72,26 +72,55 @@
7272
position: relative;
7373
transition: .3s $md-transition-default-timing;
7474
75-
.md-drawer {
76-
&.md-permanent-card + .md-content {
77-
@include md-layout-small-and-up {
78-
padding-left: 0;
79-
border-left: none;
80-
}
75+
&.md-fixed {
76+
.md-app-scroller {
77+
overflow: auto;
8178
}
8279
}
8380
84-
.md-content {
85-
padding: 16px;
86-
overflow: auto;
81+
&.md-reveal {
82+
transform: translate3d(0, 0, 0);
83+
84+
.md-app-container {
85+
padding-top: 64px;
86+
}
87+
88+
.md-app-toolbar {
89+
position: fixed;
90+
top: 0;
91+
}
92+
}
93+
}
8794
95+
.md-app-drawer {
96+
&.md-permanent-card + .md-content {
8897
@include md-layout-small-and-up {
89-
border-left: 1px solid transparent;
98+
padding-left: 0;
99+
border-left: none;
100+
}
101+
}
102+
}
103+
104+
.md-app-content {
105+
padding: 16px;
106+
107+
@include md-layout-small-and-up {
108+
border-left: 1px solid transparent;
109+
}
110+
111+
> p {
112+
&:first-child {
113+
margin-top: 0;
114+
}
115+
116+
&:last-child {
117+
margin-bottom: 0;
90118
}
91119
}
92120
}
93121
94122
.md-app-container {
123+
overflow: auto;
95124
transform: translate3D(0, 0, 0);
96125
transition: padding-left .4s $md-transition-default-timing;
97126
will-change: padding-left;

src/components/MdApp/MdAppContent.vue

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<template>
2+
<md-content class="md-app-content md-flex" v-bind="$attrs" v-on="$listeners">
3+
<slot></slot>
4+
</md-content>
5+
</template>
6+
7+
<script>
8+
export default {
9+
name: 'MdAppContent',
10+
inject: ['MdApp']
11+
}
12+
</script>

src/components/MdApp/MdAppDrawer.vue

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<template>
2+
<md-drawer class="md-app-drawer" v-bind="$attrs" v-on="$listeners">
3+
<slot></slot>
4+
</md-drawer>
5+
</template>
6+
7+
<script>
8+
export default {
9+
name: 'MdAppDrawer',
10+
inject: ['MdApp'],
11+
data: () => ({
12+
drawerElement: {
13+
mdVisible: null,
14+
mode: null
15+
}
16+
}),
17+
computed: {
18+
visible (visible) {
19+
this.MdApp.drawer.width = this.getDrawerWidth()
20+
this.MdApp.drawer.active = visible
21+
22+
return this.drawerElement.mdVisible
23+
},
24+
mode (mode) {
25+
this.MdApp.drawer.mode = mode
26+
27+
return this.drawerElement.mode
28+
}
29+
},
30+
methods: {
31+
getDrawerWidth () {
32+
let drawerWidth = this.$el ? this.$el.offsetWidth : 0
33+
34+
return drawerWidth + 'px'
35+
}
36+
},
37+
mounted () {
38+
this.drawerElement = this.$children[0]
39+
this.MdApp.drawer.width = this.getDrawerWidth()
40+
this.MdApp.drawer.active = this.visible
41+
this.MdApp.drawer.mode = this.mode
42+
}
43+
}
44+
</script>

src/components/MdApp/MdAppInternalDrawer.vue

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
<template>
2-
<div class="md-app md-app-side-drawer md-layout-column">
3-
<slot name="md-toolbar"></slot>
2+
<div class="md-app md-app-side-drawer md-layout-column" :class="appClasses">
3+
<slot name="md-app-toolbar"></slot>
44

55
<main class="md-app-container md-flex md-layout-row" :style="containerStyles">
6-
<slot name="md-drawer"></slot>
7-
8-
<slot name="md-content" class="md-flex"></slot>
6+
<slot name="md-app-drawer"></slot>
7+
<div class="md-app-scroller md-layout-column md-flex" @scroll.passive="handleScroll">
8+
<slot name="md-app-content"></slot>
9+
</div>
910
</main>
1011
</div>
1112
</template>

src/components/MdApp/MdAppMixin.js

+92-7
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,109 @@
1+
const mdAppModes = [
2+
'fixed',
3+
'fixed-last',
4+
'reveal'
5+
]
6+
7+
const customValidator = (name, source, value) => {
8+
if (source.includes(value)) {
9+
return true
10+
}
11+
12+
console.error(`The ${name} prop is invalid. Given value: ${value}. Available options: ${source.join(', ')}.`)
13+
14+
return false
15+
}
16+
117
export default {
2-
provide: {
3-
MdApp: {}
18+
props: {
19+
mdMode: {
20+
type: String,
21+
validator (value) {
22+
return customValidator('md-mode', mdAppModes, value)
23+
}
24+
},
25+
mdWaterfall: Boolean,
26+
mdFlexible: Boolean
427
},
528
data: () => ({
629
MdApp: {
7-
drawerActive: false,
8-
drawerMode: 'temporary',
9-
drawerWidth: 0
30+
options: {
31+
mode: null,
32+
waterfall: false,
33+
flexible: false
34+
},
35+
toolbar: {
36+
hasElevation: true
37+
},
38+
drawer: {
39+
active: false,
40+
mode: 'temporary',
41+
width: 0
42+
}
1043
}
1144
}),
45+
provide () {
46+
return {
47+
MdApp: this.MdApp
48+
}
49+
},
1250
computed: {
1351
containerStyles () {
14-
if (this.MdApp.drawerActive && this.MdApp.drawerMode === 'persistent') {
52+
if (this.MdApp.drawer.active && this.MdApp.drawer.mode === 'persistent') {
1553
return {
1654
'padding-left': this.MdApp.drawerWidth
1755
}
1856
}
57+
},
58+
appClasses () {
59+
return {
60+
'md-waterfall': this.mdWaterfall,
61+
'md-flexible': this.mdFlexible,
62+
'md-fixed': this.mdMode === 'fixed',
63+
'md-fixed-last': this.mdMode === 'fixed-last',
64+
'md-reveal': this.mdMode === 'reveal'
65+
}
66+
}
67+
},
68+
watch: {
69+
mdMode (mode) {
70+
this.MdApp.options.mode = mode
71+
},
72+
mdWaterfall (waterfall) {
73+
this.MdApp.options.waterfall = waterfall
74+
this.setToolbarElevation()
75+
},
76+
mdFlexible (flexible) {
77+
this.MdApp.options.flexible = flexible
78+
}
79+
},
80+
methods: {
81+
setToolbarElevation () {
82+
this.MdApp.toolbar.hasElevation = !this.mdWaterfall
83+
},
84+
handleWaterfallScroll ($event) {
85+
this.MdApp.toolbar.hasElevation = $event.target.scrollTop >= 4
86+
},
87+
handleModeScroll ($event) {
88+
/* const toolbar = this.$el.querySelector('.md-app-toolbar') */
89+
const scrollTop = $event.target.scrollTop
90+
91+
console.log(scrollTop)
92+
},
93+
handleScroll ($event) {
94+
window.requestAnimationFrame(() => {
95+
if (this.mdWaterfall) {
96+
this.handleWaterfallScroll($event)
97+
} else if (this.mdMode) {
98+
this.handleModeScroll($event)
99+
}
100+
})
19101
}
20102
},
21103
created () {
22-
this._provided.MdApp = this.MdApp
104+
this.MdApp.options.mode = this.mdMode
105+
this.MdApp.options.waterfall = this.mdWaterfall
106+
this.MdApp.options.flexible = this.mdFlexible
107+
this.setToolbarElevation()
23108
}
24109
}

src/components/MdApp/MdAppSideDrawer.vue

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
<template>
2-
<div class="md-app md-app-side-drawer md-layout-row">
3-
<slot name="md-drawer"></slot>
2+
<div class="md-app md-app-side-drawer md-layout-row" :class="appClasses">
3+
<slot name="md-app-drawer"></slot>
44

5-
<main class="md-app-container md-flex md-layout-column" :style="containerStyles">
6-
<slot name="md-toolbar"></slot>
7-
<slot name="md-content" class="md-flex"></slot>
5+
<main class="md-app-container md-flex md-layout-column" :style="containerStyles" @scroll.passive="handleScroll">
6+
<slot name="md-app-toolbar"></slot>
7+
<div class="md-app-scroller md-layout-column md-flex" @scroll.passive="handleScroll">
8+
<slot name="md-app-content"></slot>
9+
</div>
810
</main>
911
</div>
1012
</template>

0 commit comments

Comments
 (0)