Skip to content
New issue

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

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

Already on GitHub? Sign in 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

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

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in 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