JSFiddle - React, Tailwind, and code Playground

by kurotanshi

HTML

<script src="https://unpkg.com/vue@next"></script>
<div id="app">
<light-box>
  <template v-slot:header>
    <h2>008JS 好棒棒!</h2>
  </template>

  <template v-slot:footer>
    <h2>大家快來買!</h2>
  </template>

  <div>
    <a href="https://www.tenlong.com.tw/products/9789864344130">購書傳送門</a>
  </div>
</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({ });

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');