JSFiddle - React, Tailwind, and code Playground

by kurotanshi

HTML

<script src="https://unpkg.com/[email protected]/dist/vue.global.js"></script>
<div id="app">

  <!-- 子元件內是空的 -->
  <light-box></light-box>
</div>

SCSS

#app {
  position: relative;
  display: block;
  padding: 1rem;
  font-size: 1rem;
  height: 22rem;
}

button {
  font-size: 1rem;
}

.lightbox {
  position: relative;
  display: block;
  overflow: hidden;
  width: 100%;
  height: 100%;
}

.modal-mask {
  position: absolute;
  z-index: 10;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: table;
  background-color: rgba(0, 0, 0, .5);
  transition: opacity .3s ease;
}

.modal-container {
  cursor: pointer;
  display: table-cell;
  vertical-align: middle;

}

.modal-body {
  cursor: auto;
  display: block;
  width: 50%;
  margin: 0 auto;
  padding: 2rem;
  background-color: #fff;
}

JavaScript

const app = Vue.createApp({
  data() {
    return {

    }
  }
});

app.component('light-box', {
  template: `
  <div class="lightbox">
    <div class="modal-mask" :style="modalStyle">
      <div class="modal-container"  @click.self="toggleModal">

        <div class="modal-body">
          <header>
            <slot name="header">Default Header</slot>
          </header>
          <hr>
          <main>
            <slot>Default Body</slot>
          </main>
          <hr>
          <footer>
            <slot name="footer">Default Footer</slot>
          </footer>
        </div>

      </div>
    </div>

    <button @click="isShow = true">Click Me</button>
  </div>`,
  data: () => ({
    isShow: false
  }),
  computed: {
    modalStyle() {
      return {
        'display': this.isShow ? '' : 'none'
      };
    }
  },
  methods: {
    toggleModal() {
      console.log('click')
      this.isShow = !this.isShow;
    }
  }
});

app.mount('#app');