Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

fix(MdApp): right drawer, fully reactive #1493

Merged
merged 6 commits into from
May 13, 2018
Merged

fix(MdApp): right drawer, fully reactive #1493

merged 6 commits into from
May 13, 2018

Conversation

VdustR
Copy link
Member

@VdustR VdustR commented Feb 8, 2018

Changes:

  • Support right drawer with MdApp.
  • Reactive drawer
    • changing width
    • swap right / left
    • toggle drawer via v-if
  • Replace useless props mdLeft with !this.mdRight.

My test case:

<template>
  <div class="page-container md-layout-column">
    <md-app>
      <md-app-toolbar class="md-primary"><span class="md-title">Title</span></md-app-toolbar>
      <md-app-drawer :md-active.sync="open" md-persistent="full" :md-right="swap" v-if="left" :style="{width: width ? '100px' : '200px'}" style="min-width: 100px">
        <md-toolbar class="md-transparent" md-elevation="0">Left nav</md-toolbar>
        <md-switch v-model="open"></md-switch>
      </md-app-drawer>
      <md-app-drawer :md-active.sync="open" md-persistent="full" :md-right="!swap" v-if="right" style="width: 100px">
        <md-toolbar class="md-transparent" md-elevation="0">Right nav</md-toolbar>
        <md-switch v-model="open"></md-switch>
      </md-app-drawer>
      <md-app-content>
        <md-checkbox v-model="left">left</md-checkbox>
        <md-checkbox v-model="right">right</md-checkbox>
        <md-switch v-model="open">open</md-switch>
        <md-switch v-model="swap">swap</md-switch>
        <md-switch v-model="width">smaller left</md-switch>
        <p><span>test 0, </span><span>test 1, </span><span>test 2, </span><span>test 3, </span><span>test 4, </span><span>test 5, </span><span>test 6, </span><span>test 7, </span><span>test 8, </span><span>test 9, </span><span>test 10, </span><span>test 11, </span><span>test 12, </span><span>test 13, </span><span>test 14, </span><span>test 15, </span><span>test 16, </span><span>test 17, </span><span>test 18, </span><span>test 19, </span><span>test 20, </span><span>test 21, </span><span>test 22, </span><span>test 23, </span><span>test 24, </span><span>test 25, </span><span>test 26, </span><span>test 27, </span><span>test 28, </span><span>test 29, </span><span>test 30, </span><span>test 31, </span><span>test 32, </span><span>test 33, </span><span>test 34, </span><span>test 35, </span><span>test 36, </span><span>test 37, </span><span>test 38, </span><span>test 39, </span><span>test 40, </span><span>test 41, </span><span>test 42, </span><span>test 43, </span><span>test 44, </span><span>test 45, </span><span>test 46, </span><span>test 47, </span><span>test 48, </span><span>test 49, </span><span>test 50, </span><span>test 51, </span><span>test 52, </span><span>test 53, </span><span>test 54, </span><span>test 55, </span><span>test 56, </span><span>test 57, </span><span>test 58, </span><span>test 59, </span><span>test 60, </span><span>test 61, </span><span>test 62, </span><span>test 63, </span><span>test 64, </span><span>test 65, </span><span>test 66, </span><span>test 67, </span><span>test 68, </span><span>test 69, </span><span>test 70, </span><span>test 71, </span><span>test 72, </span><span>test 73, </span><span>test 74, </span><span>test 75, </span><span>test 76, </span><span>test 77, </span><span>test 78, </span><span>test 79, </span><span>test 80, </span><span>test 81, </span><span>test 82, </span><span>test 83, </span><span>test 84, </span><span>test 85, </span><span>test 86, </span><span>test 87, </span><span>test 88, </span><span>test 89, </span><span>test 90, </span><span>test 91, </span><span>test 92, </span><span>test 93, </span><span>test 94, </span><span>test 95, </span><span>test 96, </span><span>test 97, </span><span>test 98, </span><span>test 99, </span>
        </p>
      </md-app-content>
    </md-app>
  </div>
</template>

<script>
  export default {
    name: 'Temporary',
    data() {
      return {
        open: true,
        left: false,
        right: false,
        swap: false,
        width: false
      }
    }
  }
</script>

<style lang="scss" scoped>
  .page-container {
    min-height: 300px;
    overflow: hidden;
    position: relative;
    border: 1px solid rgba(#000, .12);
  }

  .md-app {
    height: 400px;
  }
  .md-app-drawer {
    width: 200px;
  }
</style>

Other bug not fixed yet:

  • style is wrong when screen width < 600px because of padding which should be 0.
    peek 2018-02-08 16-26

  • It's transition while toggle drawer v-if after :md-active
    peek 2018-02-08 16-23

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

fix #1204

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
BREAKING CHANGE: Replace useless props `mdLeft` with `!this.mdRight`

fix #1204
@marcosmoura
Copy link
Member

@VdustR Any news on that?

@VdustR
Copy link
Member Author

VdustR commented Mar 8, 2018

I've fixed that two problem mentioned before. But it's broken with other permanent and persistent cases. I need to take time to make sure all scenario work. Sorry about late resolving.

@marcosmoura
Copy link
Member

@VdustR No problem at all! Just to know if we could integrate on the new release. Let's postpone it to beta-10

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
BREAKING CHANGE: no more than one drawer in a MdApp
@VdustR
Copy link
Member Author

VdustR commented Mar 15, 2018

Update:

  • BREAKING CHANGE: no more than one drawer in a MdApp
    Because MdApp need to decide it should render as a MdAppInternalDrawer or MdAppSideDrawer. Multi drawers at a time will make it complex.
  • right drawer fully supported
  • md-permanent, md-right are reactive

Not Completed:

My test case:

<script>
  import Vue from 'vue'
  import MdAppSideDrawer from './MdAppSideDrawer'
  import MdAppInternalDrawer from './MdAppInternalDrawer'

  const componentTypes = [
    'md-app-toolbar',
    'md-app-drawer',
    'md-app-content'
  ]

  function isValidChild (componentOptions) {
    return componentOptions && componentTypes.includes(componentOptions.tag)
  }

  function buildSlots (children, context, functionalContext, options) {
    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.data.provide = options.Ctor.options.provide
          child.context = context
          child.functionalContext = functionalContext

          slots.push(child)
        }
      })
    }

    return slots
  }

  function getDrawers (children) {
    const drawerVnodes = children.filter(child => {
      return child.componentOptions.tag === 'md-app-drawer'
    })

    return drawerVnodes.length ? drawerVnodes : []
  }

  function hasInternalDrawer (attrs) {
    const mdPermanent = attrs && attrs['md-permanent']

    return mdPermanent && (mdPermanent === 'clipped' || mdPermanent === 'card')
  }

  export default {
    name: 'MdApp',
    functional: true,
    render (createElement, { children, props, data }) {
      let appComponent = MdAppSideDrawer
      const { context, functionalContext, componentOptions } = createElement(appComponent)
      const slots = buildSlots(children, context, functionalContext, componentOptions)
      const drawers = getDrawers(slots)

      drawers.forEach(drawer => {
        if (drawer && hasInternalDrawer(drawer.data.attrs)) {
          appComponent = MdAppInternalDrawer
        }
      })

      const staticClass = {}
      if (data.staticClass) {
        data.staticClass.split(/\s+/).forEach(name => {
          if (name.length === 0) return
          staticClass[name] = true
        })
      }

      return createElement(appComponent, {
        attrs: props,
        class: {...staticClass, ...data.class},
        style: {...data.staticStyle, ...data.style},
      }, slots)
    }
  }
</script>

<style lang="scss">
  @import "~components/MdAnimation/variables";
  @import "~components/MdLayout/mixins";

  .md-app {
    display: flex;
    overflow: hidden;
    position: relative;

    &.md-fixed {
      .md-app-scroller {
        overflow: auto;
      }
    }

    &.md-reveal,
    &.md-fixed-last,
    &.md-overlap,
    &.md-flexible {
      transform: translate3d(0, 0, 0);

      .md-app-toolbar {
        position: absolute;
        top: 0;
      }
    }

    &.md-flexible,
    &.md-overlap {
      .md-app-toolbar {
        min-height: 0;
      }
    }

    &.md-flexible {
      .md-toolbar-row {
        &:first-child {
          z-index: 2;
        }

        &:last-child {
          position: fixed;
          bottom: 0;
          z-index: 1;
        }
      }

      .md-display-1 {
        position: fixed;
      }
    }

    &.md-overlap {
      .md-app-toolbar {
        z-index: 1;
      }

      .md-app-content {
        margin: -64px 24px 24px;
        position: relative;
        z-index: 2;

        @include md-layout-small {
          margin: -64px 16px 16px;
        }

        @include md-layout-xsmall {
          margin: -64px 8px 8px;
        }
      }
    }
  }

  .md-app-drawer {
    &.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;
      }
    }
  }

  .md-app-content {
    padding: 16px;

    @include md-layout-small-and-up {
      border-left: 1px solid transparent;
      border-right: 1px solid transparent;
    }

    > p {
      &:first-child {
        margin-top: 0;
      }

      &:last-child {
        margin-bottom: 0;
      }
    }
  }

  .md-app-container {
    flex: 1;
    display: flex;
    overflow: auto;
    transform: translate3D(0, 0, 0);
    transition: padding-left .4s $md-transition-default-timing,
                padding-right .4s $md-transition-default-timing;
    will-change: padding-left, padding-right;
  }

  .md-app-scroller {
    flex: 1;
  }
</style>

@VdustR
Copy link
Member Author

VdustR commented Mar 15, 2018

@marcosmoura would you review for current changes now? The codes and the breaking changes.
And I need help for css that I don't know how to get the previous sibling(opposite of +)

@VdustR
Copy link
Member Author

VdustR commented Apr 8, 2018

Updated:

  • right drawer style fixed with an previous node for similar styles.
  • persistent is fully reactive now.
  • MdAppSideDrawer: fix component name

@VdustR VdustR changed the title fix(MdApp): right drawer - not completed yet, don't merge fix(MdApp): right drawer, fully reactive Apr 8, 2018
@marcosmoura marcosmoura merged commit 3ac16c7 into vuematerial:dev May 13, 2018
@VdustR VdustR deleted the fix#1204 branch May 13, 2018 20:14
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Persistent app drawer does not work when combined with md-right
2 participants