Skip to content

Instantly share code, notes, and snippets.

@d-levin
Created October 17, 2017 16:15
Show Gist options
  • Select an option

  • Save d-levin/07f1cc3d03d0bb4e895b0de7bd1f21fc to your computer and use it in GitHub Desktop.

Select an option

Save d-levin/07f1cc3d03d0bb4e895b0de7bd1f21fc to your computer and use it in GitHub Desktop.

Revisions

  1. d-levin created this gist Oct 17, 2017.
    209 changes: 209 additions & 0 deletions DashboardLayout.vue
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,209 @@
    <template>
    <div class="wrapper">
    <transition name="fade">
    <div v-if="drawerOpenOnMobile" class="overlay" @click="toggleDrawer"></div>
    </transition>
    <transition name="slide">
    <aside v-if="drawerOpen" class="drawer">
    <p>First item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Drawer item</p><p>Last item</p>
    </aside>
    </transition>
    <div class="main" :class="mainWidthClass">
    <header class="header">
    <div v-if="isMobile" class="drawer-toggle">
    <a @click="toggleDrawer" class="button is-small">
    <span class="icon is-small">
    <i class="fa fa-bars"></i>
    </span>
    </a>
    </div>
    <div class="header-left">
    <h1 class="title is-inline-block">Dashboard</h1>
    </div>
    <div class="header-right">
    <a class="button is-small">
    <span class="icon is-small">
    <i class="fa fa-ellipsis-v"></i>
    </span>
    </a>
    </div>
    </header>
    <section class="content">
    <div class="content-inner">
    <p>First content</p><p>Viral waistcoat post-ironic chicharrones, venmo tilde cardigan irony photo booth. Forage pug hashtag, small batch pickled helvetica cornhole. Cold-pressed beard microdosing, 3 wolf moon normcore banjo ugh thundercats kinfolk trust fund church-key chambray direct trade. Fashion axe copper mug pug glossier ramps. Vice kitsch kickstarter, pickled tousled post-ironic hoodie cred vexillologist beard viral poke small batch williamsburg. Retro chillwave gastropub pop-up beard. Af twee photo booth, kombucha drinking vinegar kale chips organic fingerstache vaporware coloring book keffiyeh migas pabst unicorn mumblecore. Hammock shaman enamel pin DIY raclette, ugh yr poke narwhal deep v four loko air plant copper mug. Retro la croix jean shorts live-edge, pour-over banjo chartreuse kinfolk meh kogi neutra.</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Last content</p>
    </div>
    </section>
    </div>
    </div>
    </template>

    <script>
    // Bulma mobile breakpoint
    const breakpoint = 768;
    export default {
    name: 'LayoutMain',
    data() {
    const windowWidth = window.innerWidth;
    return {
    appTitle: 'Sarkina',
    drawerOpen: windowWidth > breakpoint,
    windowWidth,
    };
    },
    computed: {
    drawerOpenOnMobile() {
    return this.drawerOpen && this.isMobile;
    },
    drawerOpenOnDesktop() {
    return this.drawerOpen && !this.isMobile;
    },
    isMobile() {
    return this.windowWidth <= breakpoint;
    },
    mainWidthClass() {
    return this.drawerOpenOnDesktop ? 'main__drawer-offset' : 'main__full-width';
    },
    },
    watch: {
    isMobile(isMobile) {
    this.drawerOpen = !isMobile;
    },
    },
    methods: {
    toggleDrawer() {
    this.drawerOpen = !this.drawerOpen;
    },
    handleWindowResize(event) {
    this.windowWidth = event.currentTarget.innerWidth;
    },
    },
    beforeDestroy() {
    window.removeEventListener('resize', this.handleWindowResize);
    },
    mounted() {
    window.addEventListener('resize', this.handleWindowResize);
    },
    };
    </script>

    <style lang="scss" scoped>
    $drawer-width: 240px;
    $drawer-z-index: 9999;
    $header-height: 55px;
    $transition-duration: 0.8s;
    @mixin shadow($shadow) {
    -webkit-box-shadow: $shadow;
    -moz-box-shadow: $shadow;
    box-shadow: $shadow;
    }
    @mixin transition($transition) {
    -webkit-transition: $transition;
    -moz-transition: $transition;
    -o-transition: $transition;
    transition: $transition;
    }
    @mixin transform($transform) {
    -webkit-transform: $transform;
    -moz-transform: $transform;
    -ms-transform: $transform;
    -o-transform: $transform;
    transform: $transform;
    }
    .wrapper {
    height: 100%;
    position: relative;
    }
    .overlay {
    position: fixed;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    background-color: rgba(black, 0.4);
    will-change: opacity;
    /* Place just below drawer */
    z-index: $drawer-z-index - 1;
    }
    .drawer {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: $drawer-width;
    padding: 1rem;
    background-color: bisque;
    overflow-y: auto;
    z-index: $drawer-z-index;
    will-change: transform;
    @include shadow(-2px 0 6px #333333);
    }
    .main {
    background-color: gray;
    position: relative;
    min-height: 100%;
    height: 100%;
    float: right;
    will-change: width;
    @include transition(width $transition-duration);
    &.main__full-width {
    width: 100%;
    }
    &.main__drawer-offset {
    width: calc(100% - #{$drawer-width});
    }
    }
    .header {
    position: fixed;
    top: 0;
    height: $header-height;
    padding: 0 1rem;
    overflow: hidden;
    width: inherit;
    background-color: lightblue;
    display: flex;
    align-items: center;
    .header-left {
    flex-grow: 1;
    }
    .drawer-toggle {
    margin-right: 1rem;
    }
    }
    .content {
    padding-top: $header-height;
    background-color: thistle;
    .content-inner {
    overflow-y: auto;
    padding: 2rem 1rem;
    }
    }
    .content,
    .content-inner {
    height: inherit;
    }
    /* Transitions */
    // Slide
    .slide-leave-active,
    .slide-enter-active {
    @include transition(transform $transition-duration);
    }
    .slide-enter,
    .slide-leave-to {
    @include transform(translateX(-100%));
    }
    // Fade
    .fade-leave-active,
    .fade-enter-active {
    @include transition(opacity $transition-duration);
    }
    .fade-enter,
    .fade-leave-to {
    opacity: 0;
    }
    </style>