<h2 class="text-center mt-3">Petite-Vue (Random Char)</h2>
<div class="row mx-3">
  <div class="col-lg-6">
    <div v-scope="{
      type: 'password', 
      show: false }" class="card card-body my-3 w-100">
      <p><strong>Show/Hide Password Generator</strong></p>
      <div class="input-group mb-1">
        <input v-bind:type="type" v-model="password" class="form-control" placeholder="Generate a password">
        <button type="button" @click="ternary(
          () => type === 'password' && show === false, 
          () => {type = 'text'; show = true}, 
          () => {type = 'password'; show = false})" class="input-group-text" title="Show/Hide Password">
          <template v-if="show">
            <!--<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-eye-slash-fill" viewBox="0 0 16 16">
              <path d="m10.79 12.912-1.614-1.615a3.5 3.5 0 0 1-4.474-4.474l-2.06-2.06C.938 6.278 0 8 0 8s3 5.5 8 5.5a7.029 7.029 0 0 0 2.79-.588zM5.21 3.088A7.028 7.028 0 0 1 8 2.5c5 0 8 5.5 8 5.5s-.939 1.721-2.641 3.238l-2.062-2.062a3.5 3.5 0 0 0-4.474-4.474L5.21 3.089z"/>
              <path d="M5.525 7.646a2.5 2.5 0 0 0 2.829 2.829l-2.83-2.829zm4.95.708-2.829-2.83a2.5 2.5 0 0 1 2.829 2.829zm3.171 6-12-12 .708-.708 12 12-.708.708z"/>
            </svg>-->
            <i class="fa fa-eye-slash"></i>
          </template>
          <template v-else>
            <!--<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-eye-fill" viewBox="0 0 16 16">
              <path d="M10.5 8a2.5 2.5 0 1 1-5 0 2.5 2.5 0 0 1 5 0z"/>
              <path d="M0 8s3-5.5 8-5.5S16 8 16 8s-3 5.5-8 5.5S0 8 0 8zm8 3.5a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7z"/>
            </svg>-->
            <i class="fa fa-eye"></i>
          </template>
        </button>
        <button type="button" class="input-group-text" @click="random">Generate</button>
      </div>
    </div>
  </div>
  <div class="col-lg-6">
    <div v-scope="{size: 25, calcSize() {
                  this.size = 25 + (/[A-Z].*[A-Z]/.test(password) ? 25 : 0) + (/[0-9].*[0-9]/.test(password) ? 25 : 0) + (/[^A-Za-z0-9_].*[^A-Za-z0-9_]/.test(password) ? 25 : 0)
                  }}" class="card card-body my-3 w-100" v-effect="calcSize()">
      <p><strong>Password Strength Indicator</strong></p>
      <div class="mb-2">
        <input type="password" v-model="password" :class="['form-control', {'is-invalid': password.length < 11 || /[A-Z].*[A-Z]/.test(password) == false || /[0-9].*[0-9]/.test(password) === false || /[^A-Za-z0-9_].*[^A-Za-z0-9_]/.test(password) === false}]" placeholder="Input a password here">
      </div>
      <div class="progress">
        <div :class="['progress-bar', 'bg-success', {'bg-danger': password.length < 11 || /[A-Z].*[A-Z]/.test(password) == false || /[0-9].*[0-9]/.test(password) === false || /[^A-Za-z0-9_].*[^A-Za-z0-9_]/.test(password) === false}]" role="progressbar" v-effect="$el.textContent = size + '%'; $el.style.width = size + '%'"></div>
      </div>
      <div class="mt-3 text-danger" v-show="password.length < 11"><span class="fs-5 align-middle">&times;</span> Password must be 11 characters long</div>
      <div class="text-danger" v-show="/[A-Z].*[A-Z]/.test(password) == false"><span class="fs-5 align-middle">&times;</span> Password must have at least 2 uppercase letters.</div>
      <div class="text-danger" v-show="/[0-9].*[0-9]/.test(password) === false"><span class="fs-5 align-middle">&times;</span> Password must contain at least 2 numbers.</div>
      <div class="text-danger" v-show="/[^A-Za-z0-9_].*[^A-Za-z0-9_]/.test(password) === false"><span class="fs-5 align-middle">&times;</span> Password must have 2 special characters or emojis.</div>
    </div>
  </div>
  <div class="col-lg-12">
    <div v-scope class="card card-body my-3 w-100">
      <p><strong>Password Validation/Confirm</strong></p>
      <div class="mb-3">
        <input type="password" v-model="password" :class="['form-control', {'is-valid': password != '' && password === confirmPassword, 'is-invalid': password !== confirmPassword}]" placeholder="Enter a new password">
      </div>
      <div class="mb-1">
        <input type="password" v-model="confirmPassword" :class="['form-control', {'is-valid': password != '' && password === confirmPassword, 'is-invalid': password !== confirmPassword}]" placeholder="Confirm your password">
        <span class="invalid-feedback">You're entering an incorrect password, please confirm your password.</span>
        <span class="valid-feedback">Password validation/confirm is available right now.</span>
      </div>
    </div>
  </div>
</div>
import { createApp } from 'https://cdn.skypack.dev/pin/petite-vue@v0.2.3-cQUfDT6SvUwIXoVO99cL/mode=imports,min/optimized/petite-vue.js'
//or https://unpkg.com/petite-vue?module
import { char, func } from 'https://cdn.skypack.dev/pin/alga-js@v0.0.1-beta6-sDOsGsFeBTBmwuVm4hMX/mode=imports,min/optimized/alga-js.js'
//or https://unpkg.com/alga-js?module

createApp({
  password: 'katasandi',
  confirmPassword: '<KataSandi2021>',
  random() {
    this.password = char.random(11, 'long') // long, short, narrow, hex, number
  },
  ternary(cb1, cb2, cb3) {
    return func.ternary(cb1, cb2, cb3)
  }
}).mount()

function random() {
  let output = ''
  let characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_~!@#$%^&*()+={}[]|:;<>,./?'
  for(let i = 0; i < 11; i++) {
    output += characters.charAt(Math.floor(Math.random() * characters.length))
  }
  return output
}

External CSS

  1. https://unpkg.com/bootstrap@5.0.2/dist/css/bootstrap.min.css
  2. https://unpkg.com/font-awesome@4.7.0/css/font-awesome.min.css

External JavaScript

This Pen doesn't use any external JavaScript resources.