JSFiddle - React, Tailwind, and code Playground

by kurotanshi

HTML

<script src="https://unpkg.com/vue@next"></script>
<div id="app">
  <p>
    請選擇:
    <select v-model="lang">
      <option v-for="n in langOptions" :value="n.val">
        {{ n.name }}
      </option>
    </select>
  </p>

  <light-box :lang="lang">
    <template v-slot:default="props">
      {{ langOptions.find(d => d.val === lang)['name'] }}:
      {{ props.hello }}
    </template>
  </light-box>
</div>

SCSS

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

.parent {
  position: relative;
  display: block;
  height: 16rem;
}

select {
  margin-bottom: 1rem;
}

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

.modal-mask {
  position: absolute;
  z-index: 10;
  top: -2rem;
  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: () => ({
    langOptions: [{
        name: '繁體中文',
        val: 'tw'
      },
      {
        name: '日本語',
        val: 'jp'
      },
      {
        name: 'English',
        val: 'en'
      },
    ],
    lang: 'tw'
  })
});

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">
            <main>
							<slot name="default"
              	v-bind:hello="helloString[lang]"></slot>
            </main>
          </div>
        </div>
      </div>

      <button @click="isShow = true">Click Me</button>
    </div>`,
  props: {
    lang: {
      type: String,
      default: 'tw'
    }
  },
  data: () => ({
    helloString: {
      'tw': '哈囉!世界!',
      'jp': 'ハロー・ワールド!',
      'en': 'Hello world!'
    },
    isShow: false
  }),
  computed: {
    modalStyle() {
      return {
        'display': this.isShow ? '' : 'none'
      };
    }
  },
  methods: {
    toggleModal() {
      console.log('click')
      this.isShow = !this.isShow;
    }
  }
});

app.mount('#app');