JSFiddle - React, Tailwind, and code Playground

Fliplet Layout Preview

by Hugo Carneiro

HTML

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://cdn.jsdelivr.net/vue/1.0.24/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-strap/1.0.11/vue-strap.js"></script>
<div class="app-canvas">
  <section class="app-page-preview with-page"></section>
  <section class="app-side-menu">
    <div class="side-content">

      <section class="side-view page-layouts">
        <header>
          <p>Click to change the layout of a screen</p>

          <a href="#">Need help?</a>
        </header>
        <main>

          <ul class="layouts">

            <template v-for="layout in layouts">
              <li class="layout">

                <div class="device-holder">
                  <popover :effect="effect" :trigger="trigger" :placement="placement" :header="header" :title="title" :content="layout.content">
                    <i class="fa fa-mobile" aria-hidden="true" @mouseover="mouseOver(layout, 'mobile')" @mouseleave="layout.content = ''"></i>
                  </popover>
                  <popover :effect="effect" :trigger="trigger" :placement="placement" :header="header" :title="title" :content="layout.content">
                    <i class="fa fa-tablet" aria-hidden="true" @mouseover="mouseOver(layout, 'tablet')" @mouseleave="layout.content = ''"></i>
                  </popover>
                  <popover :effect="effect" :trigger="trigger" :placement="placement" :header="header" :title="title" :content="layout.content">
                    <i class="fa fa-laptop" @mouseover="mouseOver(layout, 'laptop')" @mouseleave="layout.content = ''"></i>
                  </popover>
                </div>

                <p>{{layout.name}}</p>
              </li>
           ...

CSS

.app-canvas {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  bottom: 0;
}

.app-page-preview {
  -webkit-transition: background-color 650ms ease-out;
  transition: background-color 650ms ease-out;
  -webkit-box-flex: 1;
  -ms-flex: 1;
  flex: 1;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -ms-flex-direction: column;
  flex-direction: column;
  height: 100%;
  position: relative;
  overflow: hidden;
}

.app-side-menu {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  background-color: #f2f6f7;
  border-left: 1px solid #d2e0e4;
  font-size: 1.1rem;
  width: 45.3rem;
}

@media only screen and (min-width: 1681px) {
  .app-side-menu {
    width: 51.3rem;
  }
}

.app-side-menu .side-content {
  position: relative;
  -webkit-box-flex: 1;
  -ms-flex: 1;
  flex: 1;
  z-index: 1;
}

.app-side-menu .side-nav {
  width: 7.3rem;
  background-color: #434343;
  height: 100%;
  z-index: 1;
}

.side-view {
  width: 38rem;
  overflow-y: auto;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -ms-flex-direction: column;
  flex-direction: column;
  height: 100%;
  padding: 1.5rem;
  font-size: 1.4rem;
  overflow: visible;
}

@media only screen and (min-width: 1681px) {
  .side-view {
    width: 44rem;
  }
}

.side-view header {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  font-size: 0.8em;
  border-bottom: 1px solid #E3E9EB;
  margin-bottom: 3rem;
  padding-bottom: 1.5em;
}

@media only screen and (min-width: 1681px) {
  .side-view header {
    font-size: 1.0em;
  }
}

.side-view header p {
  -webkit-box-flex: 1;
  -ms-flex: 1;
  flex: 1;
  margin: 0 1.4rem 0 0;
}

a {
  color: #00abd2;
  text-decoration: none;
}

.side-view header a {
  text-decoration: none;
}

.side-view main {
  -webkit-box-flex:...

JavaScript

var popover = VueStrap.popover;
/* @mouseleave="layout.content = ''" */
new Vue({
  el: '.side-view',
  components: {
    'popover': popover
  },
  data: {
    header: false,
    placement: "left",
    effect: "fade",
    trigger: "hover",
    title: "",
    layouts: [{
      url: "https://techcrunch.com",
      name: "Hugo's Layout 1",
      content: "<iframe width='500' src='#'></iframe>"
    }, {
      url: "https://techcrunch.com",
      name: "Hugo's Layout 2",
      content: "<iframe width='500' src='#'></iframe>"
    }]
  },
  methods: {
    mouseOver: function(layout, device) {
      if (device === "mobile") {
        layout.content = '<iframe class="mobile-iframe" src="' + layout.url + '"></iframe>';
      } else if (device === "tablet") {
        layout.content = '<iframe class="tablet-iframe" src="' + layout.url + '"></iframe>';
      } else if (device === "laptop") {
        layout.content = '<iframe class="laptop-iframe" src="' + layout.url + '"></iframe>';
      }

    }
  }
});