JSFiddle - React, Tailwind, and code Playground

by khamer

HTML

<main id="app" v-if="show">
  <div class="header">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="10 10 46 46" width="66" height="66">
      <g fill="currentColor">
        <path d="M32.996 26.8c-4.618 0-10.264-.8-11.977-.848a2.166 2.166 0 00-.215-.01h-.123c-1.338.065-2.4.562-2.4 1.917s1.066 1.853 2.4 1.917h.122c.078 0 .153 0 .232-.01 1.747-.055 9.1-.286 11.9-.286 2.769 0 10.765.228 12.617.283a.4.4 0 00.412-.4v-3.017a.4.4 0 00-.412-.4c-1.85.062-8.01.854-12.556.854zm-.518-10.651c-6.212 0-8.422 3.94-8.756 8.483-.01.348.262.64.61.654 2.835.382 5.69.601 8.551.657a53.711 53.711 0 007.744-.657.642.642 0 00.61-.654c-.341-4.546-2.51-8.483-8.759-8.483zM21.703 37.934v7.359a1.03 1.03 0 001.4.96l8.653-4.066c.459-.18.968-.18 1.427 0l8.653 4.066a1.03 1.03 0 001.4-.96v-7.359a1.03 1.03 0 00-1.4-.96l-8.653 4.066c-.459.18-.968.18-1.427 0l-8.65-4.069a1.031 1.031 0 00-1.403.963z"></path>
        <path d="M32.683 38.063a4.395 4.395 0 01-3.838-2.261.649.649 0 01.252-.882.731.731 0 01.882.252 3.258 3.258 0 002.7 1.073 3.332 3.332 0 002.663-1 .7.7 0 01.889-.232.65.65 0 01.232.889 4.4 4.4 0 01-3.78 2.161z"></path>
      </g>
    </svg>
    <h1><pick :values="adjectives" :max="2"></pick> <pick :values="nouns"></pick></h1>
  </div>
  
  <button @click="refresh">not quite</button>
</main>

CSS

@import url('https://fonts.googleapis.com/css?family=Lato&display=swap');

.header {
  display: flex;
  align-items: center;
    font-family: Lato;
  color: hsl(0, 0%, 85%);
  font-weight: 300;
  justify-content: center;
  margin: 10vmin;
}

Vue

Vue.component('pick', {
  template: `<span v-text="value"/>`,
  props: {
    values: Array,
    min: {type: Number, default: 1},
    max: {type: Number, default: 1},
    and: Boolean,
    commas: {type: Boolean, default: true},
  },
  data: () => ({
    value: null,
  }),
  mounted() {
    let values = [];
    if (this.min > this.max) {
      this.max = this.min;
    }
    const numValues = this.min + Math.floor((this.max - this.min + 1) * Math.random());
    for (let i = 0; i < numValues; i++) {
      let newVal = this.values[Math.floor(this.values.length * Math.random())];
      if (this.values.includes(newVal)) {
        newVal = this.values[Math.floor(this.values.length * Math.random())];
      }
      values.push(newVal);
    }
    if (this.and && values.length > 1) {
      this.value = values.slice(0,-1).join(', ') + ' and ' + values.slice(-1)[0]
    } elseif (this.commas) {
      this.value = values.join(', ')
    } el
  },
});
new Vue({
  el: '#app',
  methods: {
    refresh() {
      this.show = false;
      requestAnimationFrame(() => this.show = true);
    },
  },
  data: {
    show: true,
    seed: null,
    adjectives: [
    	'snow', 'ice', 'frost', 'ski', 'board', 'mountain', 'chill', 'glacier',
    ],
    nouns: [
    	'butlers',
      'stewards',
      'servants',
      'getters',
      'couriers',
      'valet',
      'runners',
    ],
  },
})