JSFiddle - React, Tailwind, and code Playground

by burashka

HTML

<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
 <div class="form-group has-warning">
	<div class="col-xs-6 col-sm-4 col-md-2">
        <input type="text" id="password" placeholder="" class="form-control input-sm"/>
    </div>
	<div id="strength" class="col-xs-6 col-sm-4 col-md-2">
		<div class="progress">
		  <div role="progressbar" class="progress-bar"></div>
		</div>
	</div>
</div>

CSS

.progress {
  height: 30px;
}
.progress-bar {
  line-height: 30px;
}
.progress > .btn {
  border-color: #ADADAD;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
  height: 34px;
  line-height: 0;
  margin: -2px 0 0 -7px;
  padding: 0;
  position: absolute;
  width: 15px;
}
.progress > .btn:before {
  background: none repeat scroll 0 0 #ADADAD;
  content: " ";
  height: 21px;
  position: absolute;
  right: 6px;
  top: 6px;
  width: 1px;
}
.progress + .help-block, .progress + .strength-info {
  margin-top: -15px;
}
.strength-info {
  display: block;
}
.password-strength-very-weak {
  color: #D9534F;
}
.password-strength-very-weak .progress-bar {
  background-color: #D9534F;
  width: 20%;
}

.password-strength-weak {
  color: #F0AD4E;
}
.password-strength-weak .progress-bar {
  background-color: #F0AD4E;
  width: 40%;
}

.password-strength-medium {
  color: #5BC0DE;
}
.password-strength-medium .progress-bar {
  background-color: #5BC0DE;
  width: 60%;
}

.password-strength-strong {
  color: #428BCA;
}
.password-strength-strong .progress-bar {
  background-color: #428BCA;
  width: 80%;
}

.password-strength-very-strong {
  color: #5CB85C;
}
.password-strength-very-strong .progress-bar {
  background-color: #5CB85C;
  width: 100%;
}

JavaScript

var dcitionary, passwdqc_check;

require([
    "dojo/query",
    "dojo/dom-class",
	"dojo/domReady!"
], function(query, domClass){
    // Declare security policy
    var lowParams	 = { min: [6,  6,  6, 6, 6], max: 40, passphrase_words: 3, match_length: 4, similar_deny: 1, random_bits: 47, flags: 3, retry: 3 },
		mediumParams = { min: [8,  8,  8, 7, 6], max: 40, passphrase_words: 3, match_length: 4, similar_deny: 1, random_bits: 47, flags: 3, retry: 3 };
    
    // CSS classes for levels
    var clsMap = ["", "password-strength-very-weak", "password-strength-weak", "password-strength-medium",  "password-strength-very-strong"];
    
    var oldCls = "", timeout;
    
    // Checking value
    function check(val){
        if(val.length == 0) return 0;
        if(!passwdqc_check(val)) return 4;
        if(!passwdqc_check(val, undefined, undefined, undefined, mediumParams)) return 3;
        if(!passwdqc_check(val, undefined, undefined, undefined, lowParams)) return 2;
        return 1;
    }
    
    // Changes view
    function changeView(level){
        domClass.replace("strength", clsMap[level], oldCls);
        oldCls = clsMap[level];
    }
    
    // Listens events
    query("#password").on("keyup", function(e){
        var val = this.value;
        if(timeout) clearTimeout(timeout);
		timeout = setTimeout(function(){
		    changeView(check(val));
		}, 100);
    });
});

passwdqc_check = (function(){
  	var FIXED_BITS = 15;

	/*
	 * Calculates the expected number of different characters for a random
	 * password of a given length.  The result is rounded down.  We use this
	 * with the _requested_ minimum length (so longer passwords don't have
	 * to meet this strict requirement for their length).
	 */
	function expected_different(charset, length)
	{
		var x, y, z;

		x = ((charset - 1) << FIXED_BITS) / charset;
		y = x;
		while (--length > 0)
			y = (y * x) >> FIXED_BITS;
		z = charset * ((1 << FIXED_BITS) - y);

		return (z >> FIXED_BITS);
	}

	/*
	 * A...