diff --git a/docs/app/i18n/en-US.js b/docs/app/i18n/en-US.js index 3668be967..6170866ed 100644 --- a/docs/app/i18n/en-US.js +++ b/docs/app/i18n/en-US.js @@ -25,6 +25,9 @@ export default { title: 'Button', description: 'Buttons communicate the action that will occur when the user touches them.' }, + app: { + title: 'App' + }, checkbox: { title: 'Checkbox' }, diff --git a/docs/app/pages/Components/App/App.vue b/docs/app/pages/Components/App/App.vue new file mode 100644 index 000000000..4846f338b --- /dev/null +++ b/docs/app/pages/Components/App/App.vue @@ -0,0 +1,31 @@ + + + + + diff --git a/docs/app/pages/Components/App/examples/App.vue b/docs/app/pages/Components/App/examples/App.vue new file mode 100644 index 000000000..90e88c976 --- /dev/null +++ b/docs/app/pages/Components/App/examples/App.vue @@ -0,0 +1,46 @@ + + + + + diff --git a/docs/app/pages/Components/Drawer/examples/PermanentCard.vue b/docs/app/pages/Components/Drawer/examples/PermanentCard.vue index a25c84a78..1d6003bd5 100644 --- a/docs/app/pages/Components/Drawer/examples/PermanentCard.vue +++ b/docs/app/pages/Components/Drawer/examples/PermanentCard.vue @@ -1,10 +1,10 @@ + + diff --git a/src/components/MdApp/MdAppInternalDrawer.vue b/src/components/MdApp/MdAppInternalDrawer.vue new file mode 100644 index 000000000..39de8a64b --- /dev/null +++ b/src/components/MdApp/MdAppInternalDrawer.vue @@ -0,0 +1,28 @@ + + + + + diff --git a/src/components/MdApp/MdAppMixin.js b/src/components/MdApp/MdAppMixin.js new file mode 100644 index 000000000..d13e5d93f --- /dev/null +++ b/src/components/MdApp/MdAppMixin.js @@ -0,0 +1,24 @@ +export default { + provide: { + MdApp: {} + }, + data: () => ({ + MdApp: { + drawerActive: false, + drawerMode: 'temporary', + drawerWidth: 0 + } + }), + computed: { + containerStyles () { + if (this.MdApp.drawerActive && this.MdApp.drawerMode === 'persistent') { + return { + 'padding-left': this.MdApp.drawerWidth + } + } + } + }, + created () { + this._provided.MdApp = this.MdApp + } +} diff --git a/src/components/MdApp/MdAppSideDrawer.vue b/src/components/MdApp/MdAppSideDrawer.vue new file mode 100644 index 000000000..578a89727 --- /dev/null +++ b/src/components/MdApp/MdAppSideDrawer.vue @@ -0,0 +1,27 @@ + + + + + diff --git a/src/components/MdApp/index.js b/src/components/MdApp/index.js new file mode 100644 index 000000000..ad15b9073 --- /dev/null +++ b/src/components/MdApp/index.js @@ -0,0 +1,5 @@ +import MdApp from './MdApp' + +export default Vue => { + Vue.component(MdApp.name, MdApp) +} diff --git a/src/components/MdContent/theme.scss b/src/components/MdContent/theme.scss index 3f6b30e07..f09a7f65d 100644 --- a/src/components/MdContent/theme.scss +++ b/src/components/MdContent/theme.scss @@ -12,5 +12,9 @@ @include md-theme-property(background-color, accent); @include md-theme-property(color, text-primary, accent); } + + .md-app & { + @include md-theme-property(border-left-color, divider, background); + } } } diff --git a/src/components/MdDrawer/MdDrawer.vue b/src/components/MdDrawer/MdDrawer.vue index eb5518f6f..94cc86d5b 100644 --- a/src/components/MdDrawer/MdDrawer.vue +++ b/src/components/MdDrawer/MdDrawer.vue @@ -1,8 +1,8 @@ @@ -21,31 +21,54 @@ components: { MdOverlay }, + inject: ['MdApp'], props: { + mdLeft: Boolean, + mdRight: Boolean, mdPermanent: { type: String, - validate: value => !!drawerPermanentTypes[value] + validator (value) { + if (drawerPermanentTypes.includes(value)) { + return true + } + + console.error(`The md-permanent prop is invalid. Given value: ${value}. Available options: ${drawerPermanentTypes.join(', ')}.`) + + return false + } }, mdPersistent: Boolean, mdVisible: Boolean, mdFixed: Boolean }, - data: () => ({ - drawerWidth: null - }), watch: { mdVisible (visible) { if (visible) { this.$emit('md-opened') + } else { + this.$emit('md-closed') + } + + if (this.MdApp) { + this.MdApp.drawerWidth = this.getDrawerWidth() + this.MdApp.drawerActive = visible + } + }, + mode () { + if (this.MdApp) { + this.MdApp.drawerMode = this.mode } } }, computed: { drawerClasses () { let classes = { + 'md-left': this.mdLeft, + 'md-right': this.mdRight, 'md-temporary': this.isTemporary, 'md-persistent': this.mdPersistent, - 'md-active': this.mdVisible || this.mdPermanent, + 'md-permanent': this.mdPermanent, + 'md-active': this.mdVisible, 'md-fixed': this.mdFixed } @@ -55,34 +78,40 @@ return classes }, - drawerStyles () { - if (this.canPullDrawer) { - return { - 'margin-left': this.getDrawerWidth() - } - } - }, - canPullDrawer () { - return this.mdPersistent && !this.mdVisible - }, isTemporary () { return !this.mdPermanent && !this.mdPersistent + }, + mode () { + if (this.mdPersistent) { + return 'persistent' + } + + if (this.mdPermanent) { + return 'permanent' + } + + return 'temporary' } }, methods: { getDrawerWidth () { let drawerWidth = this.$el ? this.$el.offsetWidth : 0 - return -drawerWidth + 'px' + return drawerWidth + 'px' }, closeDrawer () { - this.$emit('md-closed') this.$emit('update:mdVisible', false) } }, + created () { + if (this.MdApp) { + this.MdApp.drawerActive = this.mdVisible + this.MdApp.drawerMode = this.mode + } + }, mounted () { - if (this.canPullDrawer) { - this.$el.style.marginLeft = this.getDrawerWidth() + if (this.MdApp) { + this.MdApp.drawerWidth = this.getDrawerWidth() } } }) @@ -93,85 +122,114 @@ @import "~components/MdLayout/mixins"; @import "~components/MdElevation/mixins"; + @mixin md-drawer-temporary () { + position: absolute; + top: 0; + bottom: 0; + left: 0; + z-index: 30; + transform: translate3D(-100%, 0, 0); + transition: transform .4s $md-transition-stand-timing; + will-change: transform, box-shadow; + } + + @mixin md-drawer-temporary-active () { + transform: translate3D(0, 0, 0); + transition-timing-function: $md-transition-default-timing; + + @include md-layout-xsmall { + @include md-elevation(16); + } + } + .md-drawer { + @include md-drawer-temporary; width: 400px; max-width: calc(100vw - 56px); - position: relative; - z-index: 1; overflow: auto; @include md-layout-xsmall { width: 320px; } + &.md-right { + right: 0; + left: auto; + transform: translate3D(100%, 0, 0); + } + + &.md-fixed { + position: fixed; + } + + &.md-active { + @include md-drawer-temporary-active; + } + + &:not(.md-temporary) { + ~ .md-overlay { + @include md-layout-small-and-up { + background: none; + pointer-events: none; + } + } + } + &.md-temporary { - position: absolute; - top: 0; - bottom: 0; - left: 0; - z-index: 30; - transform: translate3D(-100%, 0, 0); - transition: transform .4s $md-transition-stand-timing; - will-change: transform, box-shadow; - - &.md-active { - transition-timing-function: $md-transition-default-timing; - @include md-elevation(16); - transform: translate3D(0, 0, 0); + + .md-app-container .md-content { + border-left: none; } } - &.md-permanent-clipped, - &.md-permanent-card { - z-index: 1; + &.md-permanent { + @include md-layout-small-and-up { + position: relative; + transform: translate3D(0, 0, 0); + } } &.md-permanent-full { - height: 100%; - z-index: 3; + @include md-layout-small-and-up { + height: 100%; + z-index: 3; - .md-list { - padding-top: 0; + .md-list { + padding-top: 0; + } } } + &.md-permanent-clipped, &.md-permanent-card { - /* TODO: Remove styles to inherit from md-card */ - @include md-elevation(2); - margin: 16px; - overflow: hidden; - border-radius: 2px; - - @include md-layout-xsmall { - margin: 8px; + @include md-layout-small-and-up { + z-index: 1; } } - &.md-persistent { - transition: .4s $md-transition-stand-timing; - transition-property: max-width, margin-left; - will-change: max-width, margin-left; - - /* TODO: Create a way to use transform instead of margin */ - &, - ~ * { - margin-left: 0; - transform: translate3D(0, 0, 0); + &.md-permanent-card { + @include md-layout-small-and-up { + @include md-elevation(2); + margin: 8px; + overflow: hidden; + z-index: 1; + border-radius: 2px; } - &.md-active { - transition-timing-function: $md-transition-default-timing; + @include md-layout-medium-and-up { + margin: 16px; } - } - &.md-right { - right: 0; - left: auto; - transform: translate3D(100%, 0, 0); + @include md-layout-large-and-up { + margin: 24px; + } } - &.md-fixed { - position: fixed; + &.md-persistent { + &:not(.md-active) { + + .md-app-container .md-content { + border-left: none; + } + } } .md-list-item-container { diff --git a/src/components/MdLayout/mixins.scss b/src/components/MdLayout/mixins.scss index 35fcbd676..d1329b982 100644 --- a/src/components/MdLayout/mixins.scss +++ b/src/components/MdLayout/mixins.scss @@ -177,25 +177,25 @@ } @mixin md-layout-xsmall-and-up { - @media (min-width: #{$md-breakpoint-xsmall - 300px}) { + @media (min-width: 1px) { @content; } } @mixin md-layout-small-and-up { - @media (min-width: #{$md-breakpoint-small - 300px}) { + @media (min-width: #{$md-breakpoint-xsmall}) { @content; } } @mixin md-layout-medium-and-up { - @media (min-width: #{$md-breakpoint-small - 16px}) { + @media (min-width: #{$md-breakpoint-small}) { @content; } } @mixin md-layout-large-and-up { - @media (min-width: #{$md-breakpoint-medium - 16px}) { + @media (min-width: #{$md-breakpoint-medium}) { @content; } } diff --git a/src/components/index.js b/src/components/index.js index a3b90314b..5a088459a 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -1,3 +1,4 @@ +import MdApp from './MdApp' import MdButton from './MdButton' import MdCheckbox from './MdCheckbox' import MdContent from './MdContent' @@ -16,6 +17,7 @@ import MdSwitch from './MdSwitch' import MdToolbar from './MdToolbar' export default { + MdApp, MdButton, MdCheckbox, MdContent,