JSFiddle - React, Tailwind, and code Playground

by kurotanshi

HTML

<script src="https://unpkg.com/[email protected]/dist/vue.global.js"></script>
<div id="app">
  <label v-for="opt in options">
    <input type="radio" :value="opt" v-model="dynamic_slot_name"> {{ opt }}
  </label>

  <light-box>
    <template v-slot:[dynamic_slot_name]>
      <h2>008JS 好棒棒!</h2>
    </template>
  </light-box>
</div>

SCSS

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

label {
  margin-right: 1rem;
}

button {
  margin-top: 1rem;
  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 {
    	options: ['header', 'footer', 'default'],
      dynamic_slot_name: 'header'
    }
  }
});

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() {
      this.isShow = !this.isShow;
    }
  }
});

app.mount('#app');